debugging > Errors

The Ultimate React Errors Guide

In this guide we try to explain every React error you might run into. There's a mix of JavaScript, React and Babel in here to cover everything from syntax, JSX, to React Hooks.

Error: Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

The bug: You returned undefined, which is an invalid type for React's render method to return.

function App() {
// Error: Nothing was returned from render
return;
}

The fix: Return a valid type: DOM node, primitive type, array or null to return nothing.

function App() {
// Any of these are valid as return values for React render methods
// return [1,2,3];
// return <> Fragment </>
// return <div> regular DOM node </div>
// return "A String";
// Use null to return nothing inside the element
return null;
}

Error: Objects are not valid as a React child

The bug: You tried to render a JavaScript object inside your JSX

function App() {
const User = {name: 'Bob'};
// Error: Objects are not valid as a React child
return <div>
{User}
</div>
}

The fix: Render a valid React child like a string, an array, null, or DOM node.

function App() {
const User = {name: 'Bob'};
return <div>
{User.name}
</div>
}

Warning: Functions are not valid as a React child

function MyComponent(){
return <div> Hello </div>
}
function App() {
// Warning: Functions are not valid as a React child
return <div>
{MyComponent}
</div>
}

The fix: Instead of rendering the function itself, invoke the function or render the React component correctly:

function MyComponent(){
return <div> Hello </div>
}
function App() {
return <div>
<MyComponent/>
</div>
}

Error: Each child in a list should have a unique key prop

The bug: You rendered a list but didn't include a unique key as a prop for these components.

const people = [{ name: "Joe" }, { name: "Mary" }];
// Error: Each child in a list should have a unique key prop
function App() {
return (
<div>
{people.map((person) => (
<div> {person.name}</div>
))}
</div>
);
}

The Fix: Add a unique key to your list components. This is important for performance. From the react docs

React supports a key attribute. When children have keys, React uses the key to match children in the original tree with children in the subsequent tree. For example, adding a key to our inefficient example above can make the tree conversion efficient

So, where do you get a unique key from? Well, typically you would have IDs on the items from the database. If not, you could write a function to generate IDs prior to rendering in React (such as in your Redux reducer). At worst case, you could just use the index of the array, but this just hides the error, you'd still hit performance issues if you tried to modify the contents of the array.

const people = [
{ name: "Joe", id: 9345 },
{ name: "Mary", id: 3485 },
];
function App() {
return (
<div>
{people.map(({ id, name }) => (
<div key={id}> {name}</div>
))}
</div>
);
}

Error: Encountered two children with the same key

const people = [
{ name: "Joe", id: 22 },
{ name: "Mary", id: 22 },
];
// Warning: Encountered two children with the same key
function App() {
return (
<div>
{people.map(({ id, name }) => (
<div key={id}> {name}</div>
))}
</div>
);
}

The solution is to just not use the same key. Your keys must be unique.

Error: The tag is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

The bug: Starting a React component's name with a lowercase letter.

function z(){
return <div/>
}
function App() {
// Error: The tag <z> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.
return <z/>
}

The fix: Start the component's name with an uppercase letter:

function Z(){
return <div/>
}
function App() {
return <Z/>
}

Error: The style prop expects a mapping from style properties to values, not a string.

The bug: You used a string for the style prop. While this is correct syntax for standard HTML, in React world, we need to use an object for the style prop.

function App() {
// Error: The `style` prop expects a mapping from style properties to values, not a string
return <div style="background-color: blue"></div>;
}

The fix: Use a style object mapping CSS properties in camelCase.

function App() {
return <div style={{ backgroundColor: "blue" }}>rr</div>;
}

Hooks Errors

React Hooks errors typically occur due to violations of the Rules of Hooks. Be sure to review these rules. Another source of confusion may be how to use custom hooks.

Error: Hooks can only be called inside the body of a function component

import React, { useState } from "react";
// Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
const [thing, setThing] = useState();
function App() {
return <div> Hello </div>;
}

The fix: only call React hooks within React function components or custom hooks. From the rules of hooks:

Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.

Which looks like:

function App() {
const [thing, setThing] = useState();
return <div> Hello </div>;
}

Error: React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.

function App() {
// Error: React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.
if (thing) {
return null;
}
const [thing, setThing] = useState(false);
return (
<button
onClick={() => {
setThing(true);
}}
>
{" "}
Set thing{" "}
</button>
);
}

The fix: Move the react hook to the top of the function and don't return before the hook is called.

function App() {
const [thing, setThing] = useState(false);
if (thing) {
return null;
}
return (
<button
onClick={() => {
setThing(true);
}}
>
{" "}
Set thing{" "}
</button>
);
}

Error: React Hook "useState" is called in function which is neither a React function component or a custom React Hook function

The bug: While attempting to use our own custom React hook, we hit this error.

function specialHook() {
const [foo, setFoo] = useState();
return { foo };
}
function App() {
const [thing, setThing] = useState(false);
// Error: React Hook "useState" is called in function which is neither a React function component or a custom React Hook function
const foo = specialHook();
return (
<button
onClick={() => {
setThing(true);
}}
>
{" "}
Set thing{" "}
</button>
);
}

The fix: While the custom hook is used properly, it is not named properly. It must start with the word "use" for React to consider it a custom hook.

function useSpecialHook() {
const [foo, setFoo] = useState();
return { foo };
}
function App() {
const [thing, setThing] = useState(false);
const foo = useSpecialHook();
return (
<button
onClick={() => {
setThing(true);
}}
>
{" "}
Set thing{" "}
</button>
);
}

Error: Too many re-renders. React limits the number of renders to prevent an infinite loop

// Error: Too many re-renders.
function App() {
const [thing, setThing] = useState(false);
return <button onClick={setThing()}> Set thing </button>;
}

The fix: Invoking a setter within JSX will cause an infinite loop. Instead properly define an arrow function around the setter:

function App() {
const [thing, setThing] = useState(false);
return <button onClick={() => setThing()}> Set thing </button>;
}

Error: Expected listener to be a function, instead got type string

The bug: You are passing a string as a prop to an event handler like onClick:

function App() {
const [thing, setThing] = useState(false);
// Expected listener to be a function, instead got type string
return <button onClick="setThing"> Set thing </button>;
}

The fix: Properly wrap and call the event handler callback with an arrow function:

function App() {
const [thing, setThing] = useState(false);
return <button onClick={() => setThing()}> Set thing </button>;
}

Error: Cannot read property of undefined

The bug: You are attempting to access a property of an undefined object

function App() {
const user = { name: "Joe" };
// TypeError: Cannot read property 'location' of undefined
return <div> {user.address.location} </div>;
}

The fix: Either define the object you are attempting to access or safely check against it:

function App() {
const user = { name: "Joe", address: { location: "123 Street" } };
return <div> {user.address && user.address.location} </div>;
}

Babel JSX Parsing Errors

Error: Unexpected token

This bug could literally occur for hundreds of reasons. It means Babel (what compiles our JavaScript) encountered a piece of code that was unexpected. Here are some of the examples from the Babel test cases.

  • The bug: ((a)) => 42
  • The fix: ((a) => 42), a => 42
  • The bug: ...{a: 1};
  • The fix: {...{a: 1}}
  • The bug: foo ? 42
  • The fix: foo ? 42 : 24
  • The bug: { a: 1, [] };
  • The fix: { a: 1, ['foo']: 2}

Error: Unterminated comment

The bug: You tried writing a comment but you hit this error.

function App() {
/* My comment
return <div> hello </div>;
}

The fix: Finish the JavaScript comment with a closing */

function App() {
/* Finish the comment -> */
return <div> hello </div>;
}

Error: Only expressions, functions or classes are allowed as the default export

The bug: You might be surprised to find that the following is invalid syntax.

// Error: Only expressions, functions or classes are allowed as the default export
export default const foo = 'hello'

The fix: Export const can only be used with named exports, not default exports. So you have to declare the const first and then export default. There can only be one default export for each file.

const foo = 'hello';
export default foo;

From Mozilla docs:

A default export can be a function, a class, an object or anything else. This value is to be considered as the “main” exported value since it will be the simplest to import.

Error: import and export may only appear at the top level

The bug: You are attempting to use import or export within a function, possibly due to a missing bracket:

import React, { useState } from "react";
// Parsing error: 'import' and 'export' may only appear at the top level
function App() {
// missing closing parentheses
function foo(){
const x = 1;
return <div> hello </div>;
}
export default App;

The fix: closing the bracket on the foo function so export is called correctly outside on the top level scope

import React, { useState } from "react";
// Parsing error: 'import' and 'export' may only appear at the top level
function App() {
function foo() {}
const x = 1;
return <div> hello </div>;
}
export default App;

Where to get further help

If you are still having issues solving bugs, check out our debugging course we created to help you build a strategy to debug issues on your own.

🛈 React School creates templates and video courses for building beautiful apps with React. Download our free Material UI template.