REACT CODING
React problems
93 problems for the React coding round: build components and hooks in the editor, see them in the Preview, and run tests that click, type, and wait the way a user does. 24 easy, 51 medium, and 18 hard.
The tests use React Testing Library, the same tool React teams use, and run on this page. Your code is saved as you go, and hints are free. Sign in with Google to see the solutions.
93 of 93 problems
Rendering & props
- Profile cardA card for one team member, drawn from props, with a bio only when there is one and a Pro badge when
isProis true. - Tea menu listA menu of teas from an array: keyed items, prices like $4.00, sold-out teas marked with their button off, and a message when it's empty.
- Card with slotsA
Cardthat wraps any content: a title, its children, and an optional footer passed as JSX, with no empty footer when there isn't one. - BreadcrumbsBreadcrumb links from a path like /shop/teas/green, with title-cased labels and the current page marked with aria-current.
- Table from a columns configA
Tabledrawn from acolumnsconfig androws, with custom cell renderers, a caption, column headers, and an empty state. - Nested comment threadA comment thread drawn recursively, with replies in nested lists, a count of all the replies under each comment, and a button to hide them.
- File tree viewA folder tree drawn recursively from data, with folders that open and close, folders before files, everything alphabetical, and open folders that stay open.
- Fix the impure price summaryA price summary that adds to an outer variable and sorts its props while rendering, so StrictMode doubles its totals. Make it pure.
State & events
- Counter with limitsA counter with − and + buttons, a step box, and limits of 0 and 10, where each button turns off at its limit.
- Like buttonA Like button that toggles: one click adds your like, the next takes it back, and
aria-pressedsays which. - Show passwordA password box with a Show password button that switches it between hidden and shown, without losing what you typed.
- Character counterA 140-character note box that counts down, warns near the limit, and turns Post off when the note is too long.
- Temperature converterTwo boxes, Celsius and Fahrenheit, that fill each other in from one piece of state, with a message for anything that isn't a number.
- Color swatchesPick a tin color from a group of swatches that works as a radio group, with a preview of the chosen color and arrow keys that move the choice.
- Fix the order counterFix an order counter whose +3 adds only one and whose delayed +1 throws away clicks: queue state updates instead of reading a stale count.
- Accordion with one panel openA list of questions where opening one answer closes the others, with
aria-expandedandaria-controlson every title. - To-do list with filtersAdd, tick off, and delete tasks, filter them by All, Active, or Done, and count the tasks left.
- Shopping cart with quantitiesA tea shop cart: add teas, change quantities with + and −, and keep the totals right, without changing the arrays you're given.
Forms
- Password strength meterA password box with a live checklist of four rules and a Weak, Fair, or Strong rating worked out from how many are met.
- Dependent selectsA country select and a city select that lists only that country's cities, stays disabled until a country is chosen, and resets when it changes.
- Tag inputA text box that turns what you type into tags on Enter or comma, skips duplicates, and removes tags with Backspace or their own button.
- Select all checkboxesA checklist with a Select all box that's checked, unchecked, or indeterminate to match the items, set through a ref, plus a count.
- Dynamic ingredient fieldsA recipe form where you add and remove ingredient rows, each row keeps what you typed, and saving sends the list.
- Sign-up form with validationA sign-up form whose errors appear once you leave a field, follow what you type, and keep Sign up disabled until every field is valid.
- One-time code inputSix one-digit boxes for a sign-in code: focus moves as you type and delete, pasting fills them, and onComplete gets the full code.
- Multi-step checkout formA three-step checkout where Next checks the current step, Back keeps every value, a progress list marks the step, and Place order sends it all.
Effects & timers
- Unread count in the tab titleKeep the browser tab's title as
(3) Inboxfrom an unread count, and put the old title back when the component leaves. - Online statusShow Online or Offline from
navigator.onLine, kept up to date by the browser'sonlineandofflineevents throughuseSyncExternalStore. - Traffic lightA traffic light that cycles red, green, yellow on timers set by props, and leaves no timer behind when it's removed.
- StopwatchA stopwatch that counts tenths of a second, with Start, Stop, and Reset, and no interval left running.
- Keyboard shortcuts helpOpen a help panel with
?and close it with Escape, ignoring keys typed into text boxes and removing the listener on unmount. - Fix the effect loopFix a tea finder whose Effect keeps setting the state it depends on, and whose notice timer restarts on every render.
- Autosave a draftA note box that saves to
localStoragehalf a second after typing stops, shows Saving… and Saved, and loads the draft when it appears. - Countdown timerCount down from a number of seconds as mm:ss, with Pause and Resume, an
onDonecall at zero, and a fresh start when the prop changes.
Data fetching
- User profile fetchA profile card that fetches one user, shows loading and errors with Retry, and fetches again when the id changes.
- Abort on unmountA tea panel that cancels its request with an AbortController when it closes or switches tea, and treats the abort as nothing to report.
- Polling order statusAn order tracker that checks the order every 2 seconds until it's delivered, shows when it last heard back, and stops cleanly.
- Load more feedA feed whose Load more button adds the next page to the end, can't load a page twice, and goes away when there's nothing left.
- Paginated listAn order history that fetches one page at a time, with Previous and Next, and keeps the old page on screen, dimmed, while the next one loads.
- Search without racesA search box that fetches as you type, shows loading and errors, and never shows results for an older search that answered late.
- Cached fetchTabs that fetch each tea list once, show it again instantly when you come back, and refetch only when you press Refresh.
- Optimistic like with rollbackA like button that updates at once, saves in the background, rolls back on failure, and stays right however fast you click.
Custom hooks
- useToggleA hook for an on/off value:
const [on, toggle] = useToggle(), wheretoggleflips it or sets it. - useCounterA counter hook with optional limits and a step:
{ count, increment, decrement, reset }, where the count stops at its limits. - usePreviousA hook that returns what a value was before it last changed, like a tea's old price next to its new one.
- useDebouncedValueA hook that returns a value only once it has stopped changing for a while, so a search waits until the customer pauses typing.
- useIntervalA hook that calls the latest callback every
delayms without restarting its interval, and pauses whendelayis null. - useClickOutsideA hook that calls a handler when the pointer goes down outside an element, the way menus and popovers close.
- useMediaQueryA hook that tells you whether a CSS media query matches, read with
useSyncExternalStoreand safe for server rendering. - useLocalStorageLike
useState, but saved inlocalStorageas JSON, read once, safe with bad data, and kept in step with other tabs. - useUndoUndo and redo for any value, with the history in a pure reducer:
{ value, set, undo, redo, canUndo, canRedo }. - useFetchA data hook,
{ data, error, loading, refetch }, that cancels requests it no longer needs and never shows an old answer.
Context & reducers
- Theme contextA
ThemeProviderand auseTheme()hook, so any component deep in the tree can read the theme and toggle it. - Sign-in gateAn
AuthProviderwithloginandlogout, and aRequireAuthwrapper that shows its children only to a signed-in user and a sign-in form otherwise. - Cart reducerMove a cart's update logic into a pure
cartReducerwith add, remove, change quantity, and empty actions, and drive the cart withuseReducer. - Form state machine reducerA newsletter form whose state is one status,
editing,submitting,success, orerror, moved by a reducer that ignores moves that make no sense. - Cart with a reducer and contextCombine a reducer with context: a
CartProvideranduseCart()that keep a header badge and a product list in different branches in sync. - Toast notificationsA
ToastProvideranduseToast(): any component can callshow(message, { duration }), and toasts stack, close themselves on time, and can be dismissed. - Split a context to save rendersA cart provider re-renders every consumer on every change. Split state and actions so components that only dispatch never render again.
UI components
- TooltipA button with a tooltip that shows on hover or focus after a short delay, hides on leave, blur, or Escape, and is linked with aria-describedby.
- Star ratingFive stars that work like radio buttons: click or use the arrows to rate, hover to preview, and a read-only mode.
- Pagination controlsPage buttons that collapse into ellipses, like 1 … 4 5 6 … 20, with Previous and Next and the current page marked.
- Transfer listTwo lists of teas with checkboxes, where buttons move the checked ones, or all of them, from one side to the other.
- Sortable, filterable tableA table of teas you sort by clicking a header (with aria-sort), narrow with a filter box, and that sorts numbers as numbers.
- Image carouselA carousel with Previous and Next that wrap around, dots to jump, and an optional autoplay that pauses on hover and focus.
- Tabs with keyboard supportAccessible tabs: a tablist with roving tabindex, where the arrow keys, Home, and End move between tabs.
- Progress bars with a queueAn Add button that adds progress bars which fill over 2 seconds, with at most three filling at once and the rest waiting their turn.
- Dropdown menuA menu button that opens with the mouse or keyboard, moves through its items with the arrows, and hands the focus back when it closes.
- AutocompleteA combobox that filters a list as you type, moves through matches with the arrows via aria-activedescendant, and picks with Enter or a click.
- Nested checkboxesA tree of checkboxes where a parent checks all its children, and the children decide whether the parent is checked, unchecked, or indeterminate.
- Modal dialogA modal that renders in a portal, takes the focus, keeps Tab inside, closes on Escape, and gives the focus back.
Performance
- Memoize an expensive filterA slow filter runs on every keystroke, even in the order note box. Keep its result with useMemo so it runs only when its inputs change.
- Stable callbacks for memo childrenMemoized cup buttons and a note box still render on every change, because their parent passes new functions. Keep them the same with useCallback.
- Rows that skip renderingTyping in a tea menu's filter box renders every row again. Make rows that didn't change skip rendering with memo and stable props.
- Move state away from a slow chartTyping in a search box and toggling the text size both render a slow sales chart. Restructure the page so the chart renders once.
- Deferred search resultsKeep a search box responsive next to a slow results list with useDeferredValue, and mark the old results as stale while new ones render.
- Virtualized listShow 10,000 order rows by rendering only the ones in view plus a few extra, inside a spacer as tall as the whole list.
Actions, Suspense & transitions
- Submit button with useFormStatusA reusable SubmitButton that reads its parent form's status: it says Saving… and turns itself off while the form's action runs.
- Lazy-loaded sales chartLoad a heavy chart component with lazy() only when Show chart is pressed, with a Suspense fallback while its code downloads.
- Newsletter form with useActionStateA sign-up form whose async action returns the next state: a pending button, field errors, a thank-you, and a box that empties when it works.
- Error boundary with Try againA class ErrorBoundary whose fallback shows the error and a Try again button, and that also resets itself when its resetKeys change.
- Tea details with use and SuspenseRead a cached promise with use() inside Suspense: a fallback while a tea loads, then its details, and no second fetch for a tea already loaded.
- Tabs that wait with transitionsTabs that switch inside startTransition: a slow tab keeps the old one on screen and marks its own button busy, and another click can cut in.
- Tabs that keep their state with ActivityTwo tabs wrapped in Activity: a hidden tab keeps its typed note and received orders, and its subscription stops while it's hidden.
- Optimistic chat messagesA chat that shows your message at once with Sending…, swaps in the saved one when the server answers, and offers Retry when it fails.
Apps & games
- Poll widgetA one-vote poll: pick an option, see each one's share as a percentage and a bar, change your mind, and see the total.
- Kanban boardA three-column task board: move cards left and right, add new ones, and show how many cards each column holds.
- Tic-tac-toeTic-tac-toe for two players: turns, wins in any line, draws, a restart, and a move history you can jump back through.
- Typing speed testType a passage while each character turns right or wrong; a clock starts at your first key and the end shows your WPM and accuracy.
- Grid lightsLight up the cells of a 3 by 3 grid; once all are lit, they turn off one at a time in reverse order, every 300 ms.
- Memory gameA card-matching game: turn two cards over, keep the pairs, flip mismatches back after a second, and count the moves.
- Connect fourTwo players drop discs into a 7 by 6 board until someone lines up four across, down, or diagonally, or the board fills.
- Five-letter word gameGuess a five-letter word in six tries, typing on the keyboard, with each letter marked correct, present, or absent, repeated letters included.