React makes building user interfaces easier, but certain errors appear repeatedly, especially when working with components, state, props, effects, and lists. Understanding these errors can save hours of debugging.

1. “Objects are not valid as a React child”

This happens when you try to render a JavaScript object directly.

const user = {
  name: "John",
  age: 25
};

return <h1>{user}</h1>;

React cannot render the object itself.

Fix:

return <h1>{user.name}</h1>;

Or, for debugging:

<pre>{JSON.stringify(user, null, 2)}</pre>

2. Missing key Prop in Lists

When rendering arrays, React expects each element to have a unique key.

const users = ["John", "Jane", "Mike"];

return (
  <ul>
    {users.map(user => (
      <li>{user}</li>
    ))}
  </ul>
);

You may see:

Each child in a list should have a unique "key" prop.

Fix:

{users.map(user => (
  <li key={user}>{user}</li>
))}

Keys help React identify which items have changed, been added, or removed.

Avoid using array indexes as keys when the list can be reordered or modified.

3. “Cannot read properties of undefined”

A component may try to access a property before the data exists.

<h1>{user.name}</h1>

If user is initially undefined, this can cause an error.

Fix with optional chaining:

<h1>{user?.name}</h1>

Or conditionally render the component:

{user && <h1>{user.name}</h1>}

4. Updating State Incorrectly

State updates should use the state setter rather than directly modifying the state variable.

Incorrect:

count = count + 1;

Correct:

setCount(count + 1);

For updates based on the previous state, use the functional form:

setCount(prevCount => prevCount + 1);

This is particularly important when multiple state updates may be batched.

5. Infinite useEffect Loops

An incorrectly configured effect can run continuously.

useEffect(() => {
  setCount(count + 1);
}, [count]);

The effect changes count, which causes the effect to run again, creating a loop.

The solution depends on the intended behavior. If the effect should run only once when the component mounts:

useEffect(() => {
  // logic
}, []);

Do not simply remove dependencies to silence a warning. The dependency array should represent the values the effect actually uses.

6. Calling Hooks Conditionally

Hooks must be called in the same order on every render.

Incorrect:

if (isLoggedIn) {
  useEffect(() => {
    // ...
  }, []);
}

Correct:

useEffect(() => {
  if (isLoggedIn) {
    // ...
  }
}, [isLoggedIn]);

The same rule applies to useStateuseMemouseCallback, and other Hooks.

7. Forgetting to Return JSX

A component must return the UI it is supposed to render.

Incorrect:

function Welcome() {
  <h1>Hello</h1>;
}

Correct:

function Welcome() {
  return <h1>Hello</h1>;
}

For arrow functions, be careful with curly braces:

const Welcome = () => (
  <h1>Hello</h1>
);

8. Incorrect Event Handler

This mistake calls the function immediately instead of passing it as an event handler.

Incorrect:

<button onClick={handleClick()}>
  Click
</button>

Correct:

<button onClick={handleClick}>
  Click
</button>

If arguments are required:

<button onClick={() => handleClick(id)}>
  Click
</button>

9. Using class Instead of className

JSX uses className for CSS classes.

Incorrect:

<div class="container">
  Hello
</div>

Correct:

<div className="container">
  Hello
</div>

This is because class is a JavaScript keyword-related attribute conflict in JSX’s DOM property model.

10. Component Name Starts With a Lowercase Letter

React treats lowercase JSX tags as HTML elements.

function profile() {
  return <h1>Profile</h1>;
}

<profile />

React interprets <profile /> as a custom HTML-like element rather than your React component.

Use PascalCase:

function Profile() {
  return <h1>Profile</h1>;
}

<Profile />

11. State Updates Don’t Happen Immediately

This can be confusing:

setCount(count + 1);

console.log(count);

The console.log may still show the previous value because React schedules state updates rather than changing the variable immediately.

If you need to perform something when the value changes:

useEffect(() => {
  console.log(count);
}, [count]);

12. Props Are Read-Only

You should not directly modify props inside a component.

Incorrect:

function User({ name }) {
  name = "Mike";

  return <h1>{name}</h1>;
}

Instead, use state if the component needs to manage a changing value:

function User({ name }) {
  const [currentName, setCurrentName] = useState(name);

  return <h1>{currentName}</h1>;
}

13. Import/Export Errors

A common error occurs when a default export is imported as a named export, or vice versa.

Default export:

export default Button;

Import:

import Button from "./Button";

Named export:

export { Button };

Import:

import { Button } from "./Button";

The export and import syntax must match.

14. “Too Many Re-renders”

This usually happens when something triggers a state update during rendering.

Incorrect:

function Counter() {
  const [count, setCount] = useState(0);

  setCount(count + 1);

  return <h1>{count}</h1>;
}

Every render updates the state, which causes another render.

Move the update into an event handler or an appropriately configured effect:

<button onClick={() => setCount(count + 1)}>
  Increment
</button>

15. Rendering Before Data Is Available

Data from an API is often unavailable during the first render.

Instead of assuming it exists:

return <h1>{data.user.name}</h1>;

Handle loading and missing data:

if (loading) {
  return <p>Loading...</p>;
}

if (!data) {
  return <p>No data found.</p>;
}

return <h1>{data.user.name}</h1>;

This makes components much more resilient.

Quick Debugging Checklist

When a React application throws an error, check:

  • Console: Read the complete error message and stack trace.
  • Props: Is the expected data actually being passed?
  • State: Could the value initially be undefined or null?
  • Lists: Does every rendered list item have a stable key?
  • Hooks: Are Hooks being called at the top level?
  • Effects: Are dependencies correct?
  • Events: Are handlers being passed rather than immediately executed?
  • Imports: Do your named/default exports match?
  • Rendering: Are you accidentally trying to render an object?
  • State updates: Are you modifying state through its setter?

Most React errors become much easier to solve once you identify what React expected, what it actually received, and which component introduced the mismatch.

Share
Published by
codeflare

Recent Posts

C Programming Cheat Sheet

The C programming language is a foundational, general-purpose computer programming language created by Dennis Ritchie at Bell Labs in 1972. Originally developed to…

9 hours ago

Homebrew Tutorial

What Is Homebrew? Homebrew is a package manager for macOS and Linux that makes it easy to…

4 days ago

10 Ways to Loop Through a JavaScript Array

JavaScript gives you several ways to iterate over an array. Some are better for simple…

6 days ago

Build a Node JS Web Server

A web server is the software responsible for receiving requests from clients, processing those requests,…

1 week ago

Shell Prompt Tutorial

A shell prompt is the text displayed by a command-line shell to show that it is ready…

2 weeks ago

The SOC Analyst

A SOC Analyst (Security Operations Center Analyst) is one of the frontline defenders of an organization’s cybersecurity…

3 weeks ago