Skip to content

React Tutorial Advanced React Concepts

Common React Rendering Mistakes and How to Avoid Them

Lesson 125 of 156 3 min read By Deepak Paswan Updated Oct 10, 2026

Runnable lesson · press Try it on the examples to edit and run them here.

These are the rendering mistakes that fill forums and code reviews. Each one has a symptom, a cause and a fix.

1. Defining a component inside another component

Symptom: inputs lose focus or state resets on every keystroke.

App.jsx
JSX
function Wrong() {
  const [text, setText] = React.useState("");
  // WRONG: a brand-new component type on every render, so React unmounts and remounts it
  function Field() {
    return <input aria-label="Name" value={text} onChange={(e) => setText(e.target.value)} />;
  }
  return <div><p>Parent renders</p><Field /></div>;
}

function App() { return <Wrong />; }

Try it: type in the box. After the first letter the input loses focus, so only one letter registers, because the whole input is recreated on every keystroke. Cause: Field is a different function each render, so React sees a different component type and replaces it. Fix: define components at the top level of the file, and pass what they need as props.

App.jsx
JSX
function Field({ value, onChange }) {
  return <input aria-label="Name" value={value} onChange={onChange} />;
}

function App() {
  const [text, setText] = React.useState("");
  return <div><p>Parent renders</p><Field value={text} onChange={(e) => setText(e.target.value)} /></div>;
}

2. Setting state during render

Symptom: “Too many re-renders” error.

App.jsx
JSX
function App() {
  const [count, setCount] = React.useState(0);
  setCount(count + 1);   // WRONG: causes a render, which sets state, which causes a render...
  return <p>{count}</p>;
}

Fix: change state in event handlers or effects, never directly in the body. Also watch for onClick={setCount(1)} (a call instead of a function): write onClick={() => setCount(1)}.

3. Calling a handler instead of passing it

App.jsx
JSX
<button onClick={handleClick()}>   // runs while rendering
<button onClick={handleClick}>     // correct
<button onClick={() => handleClick(id)}>  // correct, with an argument

4. Missing or unstable keys

Symptom: console warning; state jumps between rows; slow lists. Fix: a stable, unique key from your data, not the index and not Math.random() (a random key changes every render, so every row is remounted). See Understanding React Keys.

5. Mutating state or props

Symptom: the screen does not update, or updates late. Fix: always set new objects and arrays (Avoiding State Mutation).

6. Reading state right after setting it

Symptom: a handler uses the old value. Fix: use the value you computed, or an updater function (State as a Snapshot).

7. Storing derived values in state

Symptom: two values that disagree. Fix: calculate during render (Derived State).

8. An effect for everything

Symptom: extra renders, flickering, loops. Fix: Do You Need an Effect?

9. Rendering 0 or objects by accident

{count && <X />} shows 0; {someObject} throws “Objects are not valid as a React child”. Fix: count > 0 &&; render fields, not objects (Rendering Dynamic Values).

10. Forgetting return in map

App.jsx
JSX
items.map((item) => { <li>{item}</li> })     // returns undefined: nothing renders
items.map((item) => <li>{item}</li>)         // returns the element

11. Calling hooks conditionally

Symptom: “Rendered more hooks than during the previous render”. Fix: Rules of Hooks.

12. New objects and functions in props, breaking memoization

App.jsx
JSX
<Child options={{ a: 1 }} onSave={() => save()} />   // new references each render

Fine for ordinary components. When Child is memo-wrapped or the value is an effect dependency, create stable values with useMemo/useCallback or move them outside the component (Performance Optimization).

13. Using index as key and then reordering

Covered in Understanding React Keys, with a live demonstration.

14. Rendering huge lists

Symptom: slow scrolling and typing. Fix: paginate, virtualize or filter first (Pagination).

15. Impure rendering

Writing to variables outside the component, or using Math.random()/Date.now() for output during render. Symptom: differences in Strict Mode, hydration mismatches in server-rendered apps. Fix: keep render pure (React Strict Mode).

A debugging habit

When the screen is wrong, ask three questions in order:

  1. What is the state and what are the props right now? (React DevTools, or console.log at the top of the component.)
  2. Did the component re-render? If not, state was mutated or the setter got the same value.
  3. Is it rendering the right thing for that state? If not, the JSX logic is wrong.

Key points

  • Define components at the top level; never call hooks or set state during render.
  • Use stable keys, immutable updates and derived values.
  • Debug by checking state, then whether it re-rendered, then the JSX logic.