A React UI code review should connect each implementation decision to something a person can see or do. Does editing a row preserve the correct input? Does switching accounts clear the previous account's draft? Does the Cancel button accidentally submit the form?
Use the checklist below when a pull request changes an existing React screen or shared component. It focuses on UI behavior. Keep the project's security, data-access, and business-logic review alongside it.
The checklist at a glance
| Check | Question to answer | Useful evidence |
|---|---|---|
| Component reuse | Does an existing primitive support this behavior? | Its API and an existing call site |
| List identity | Does state stay with the correct item? | Edit a row, then reorder the list |
| State lifecycle | Which changes should preserve or reset input? | Switch records with a draft present |
| Derived values | Is duplicated state creating extra synchronization? | Trace the value back to its inputs |
| Render purity | Can rendering change anything outside itself? | Inspect mutations and side effects |
| Control semantics | Does each action have the right element and name? | Keyboard and form interaction |
| Component states | Does the UI explain pending, empty, and failed work? | A small set of explicit fixtures |
| Change boundaries | Does the fix preserve existing consumers? | Representative usages of the changed API |
1. Compare the new component with what already exists
Before reviewing twenty utility classes on a new button, inspect the existing Button component. Compare its size variants, disabled behavior, loading treatment, and supported element type with the proposed usage.
Recommend reuse only when the contracts match. A navigation link and a form submit action may share styling while requiring different semantics. If the existing component lacks a necessary behavior, describe that gap instead of demanding a replacement based on appearance alone.
Write the review comment around the concrete alternative: “This can use the existing secondary variant; its loading state already reserves the label width.” If duplication is recurring, use the design system consistency audit to investigate beyond one PR.
2. Follow identity through changing lists
React uses keys to match list items between renders. A stable identifier from the data is appropriate for an editable list that can be reordered, filtered, or have rows inserted. Index-based keys can associate retained state with the wrong item after those changes. React's list guidance explains the identity problem.
For an illustrative review exercise, consider these alternatives:
The useful verification is behavioral: enter unsaved text in one task, move another task above it, and check which task still owns the text. These snippets illustrate the review question; they are not a tested application patch.
3. Decide when local state should reset
React associates state with a component's position and identity in the render tree. Changing the key can deliberately reset it; removing the component also discards its state. React documents these preservation rules.
For a customer editor, decide whether switching customers should discard an unsaved draft, preserve separate drafts, or prompt first. Then inspect whether the implementation actually enforces that decision. A reset is not automatically a bug, and preserved state is not automatically correct.
Include this expected behavior in the PR description when it is easy to misinterpret.
4. Question state that only copies other state
A filtered list, formatted label, or selected-item count can often be calculated from existing props and state during rendering. Copying such values into state through an Effect adds synchronization work and an extra render cycle. Effects remain appropriate for synchronizing with external systems. React's Effect guidance makes this distinction.
Ask the author to identify the source of truth. If the count is derived from selected IDs, review the derivation rather than maintaining a second counter that every selection path must remember to update.
5. Keep render-time work free of outside effects
Components should not mutate props or state snapshots, and side effects should run outside rendering. These constraints let React render and schedule work predictably. React's purity rules cover both requirements.
During review, look for a sort that mutates an incoming array, a write to a shared object, or an analytics call in the component body. Ask what happens if React renders the component again before committing the result.
6. Inspect the actual HTML contract
Check a control's element, accessible name, and form role together. A button inside a form may submit it unless its type says otherwise; use an explicit type="button" for a non-submit action. MDN's button reference describes this behavior.
Form labels must be associated with their controls. Nearby text alone does not create that relationship. In JSX, verify either a matching input id and label htmlFor, or an input nested inside its label. Then confirm the rendered association. W3C's labeling tutorial explains explicit and implicit labels.
7. Review a state matrix, not just populated data
For the changed feature, request fixtures for loading, no results, a failed request, long content, and restricted access when applicable. Add one transition such as retrying after failure or saving while the network is slow.
Record what remains uncertain. A static error fixture establishes layout and copy; it does not demonstrate that a real failed request reaches that state. The AI-generated UI review checklist provides a broader release pass.
8. Close with a reproducible finding
A useful comment names the trigger, observed behavior, expected behavior, and smallest justified change. For a shared component, include another consumer that should be rechecked. Avoid turning an unrelated style preference into a merge requirement.
Design Bug Bot adds repository-aware UI findings and suggested code to GitHub reviews. Validate changes against the states that matter to your feature.
Frequently asked
- Should every React PR use the entire checklist?
- Use the relevant rows. A copy-only change needs less review than a new editable list or a shared component API change. Explain omitted checks when the coverage matters.
- Does a passing typecheck prove the UI is correct?
- Treat it as one input to review. The checklist asks for behavioral evidence too, such as preserving the intended draft or displaying a failed request clearly.