React JS: Rendered fewer hooks than expected. This may be caused by an accidental early return statement

Asked
Active3 hr before
Viewed126 times

10 Answers

hooksreact
90%

The problem is that in the first render, 3 useState hooks were invoked - name, age and license but after the age is changed to a value below 16, the useState for license is no longer invoked, resulting in only the first 2 hooks being invoked. As the React docs state:,So I also experienced this error, but it was not related to the hook being wrapped in a condition. Instead it was caused by me having bad key values.,The issue was that I used the index as a key, thus when I dragged a new element on top it got the same key as the locked element, the value of ref was changed and React complained with the above error.

const {useState} = React;

function App() {
  const [name, setName] = useState('Mary');
  const [age, setAge] = useState(16);
  const [license, setLicense] = useState('A123456');

  return (
    <div>
      Name:{' '}
      <input
        value={name}
        onChange={e => {
          setName(e.target.value);
        }}
      />
      <br />
      Age:{' '}
      <input
        value={age}
        type="number"
        onChange={e => {
          setAge(+e.target.value);
        }}
      />
      {age >= 16 && <span>
        <br />
        Driver License:{' '}
        <input
          value={license}
          onChange={e => {
            setLicense(e.target.value);
          }}
        /></span>
       }
    </div>
  );
}

ReactDOM.render(<App />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
load more v
88%

Move your condition under the useEffect.

useEffect(() => {})

if (context.token) {
  return <Redirect to="/" />;
}
load more v
72%

I was able to solve this problem by using component syntax instead of function syntax. I‘m not sure why, but it fixed my problem.,For now, I’ll be using <Component value={value} /> syntax instead of function syntax Component({id}) when dealing with React hooks!,Further, pass the component around using Component syntax <MyComponent /> instead of calling the function component directly myComponent() !

This is the first, most obvious, issue which can cause the Rendered fewer hooks than expected error.

export default function ListView({
   history,
   match
}) {
   const filter = match.params.filter
   let [items, maxPages] = useTopStories(filter, page) // don't use hooks within a conditional statement!  if (filter === 'jobs') {  const [jobs, setJobs] = useState([]) }  //...}
load more v
65%

The problem is that in the first render, 3 useState hooks were invoked - name, age and license but after the age is changed to a value below 16, the useState for license is no longer invoked, resulting in only the first 2 hooks being invoked. As the React docs state:,The solution is to move the license hook up to the top of the function so that it gets called regardless whether it is needed or not.,The order of the hooks being called is important, and if we write code that causes hooks to not be called, React will not be able to match the hook call with its values.

const {useState} = React;

function App() {
  const [name, setName] = useState('Mary');
  const [age, setAge] = useState(16);
  const [license, setLicense] = useState('A123456');

  return (
    <div>
      Name:{' '}
      <input
        value={name}
        onChange={e => {
          setName(e.target.value);
        }}
      />
      <br />
      Age:{' '}
      <input
        value={age}
        type="number"
        onChange={e => {
          setAge(+e.target.value);
        }}
      />
      {age >= 16 && <span>
        <br />
        Driver License:{' '}
        <input
          value={license}
          onChange={e => {
            setLicense(e.target.value);
          }}
        /></span>
       }
    </div>
  );
}

ReactDOM.render(<App />, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
load more v
75%

In this lesson we'll see an interesting situation where we're actually calling a function component and getting a dreaded React error: "Rendered fewer hooks than expected." We'll learn why that is happening, how it can be avoided, and how our "workaround" fixes the problem and avoids potential bugs.,4Fix "React Error: Rendered fewer hooks than expected" 4m 17s,This is based on my blog post: Don't call a React function component

 Pretag team - issue, fix, solve, resolve
40%

Do you want to request a feature or report a bug? Bug What is the current behavior?,What is the expected behavior? Just works Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React? 16.7-alpha0 / MacOS High Sierra,I figured out the problem; it is related to rendering JSX from a function without using React.createElement. For example

Rendered fewer hooks than expected.This may be caused by an accidental early
return statement.▶17 stack frames were collapsed.
MediaQueryList.listener
src / hooks / media.ts: 103
100 | )
101 |
   const listener = () => {
      102 | console.log(mediaQueryList.matches) >
         103 | setMatches(mediaQueryList.matches) |
         ^ 104 |
   }
105 |
   106 | useEffect(() => {
load more v
22%

これがでたあなた。 恐らく 原因はmapで回すrender関数とHooksの相性が悪いことのような気がしています, Instantly share code, notes, and snippets. ,render関数を使っているところを疑ってください。

// コードは適当です
const render = (props) => ((item, index) => {
const callback = useCallback(props.callback, [])
const memo = useMemo(some...)
                return (
                <Component
                    key={item.id}
                    label={item.name}
                    onClick={createClickButtonDom(props.onClickItem, item.name)}
                    width={item.width}
                    active={}
                />)
            }
        )
}
export const Component = React.memo<Props>(props => 
    <Wrap>
        {props.items.map(render(props))}
    </Wrap>
))
load more v
60%

If you are on a personal connection, like at home, you can run an anti-virus scan on your device to make sure it is not infected with malware.,If you are at an office or shared network, you can ask the network administrator to run a scan across the network looking for misconfigured or infected devices.,Please enable Cookies and reload the page.

 Pretag team - issue, fix, solve, resolve
48%

How Uncaught Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement in React Hooks Error Occurs?,How To Solve Uncaught Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement in React Hooks Error?,Hello Guys, How are you all? Hope You all Are Fine. Today I get the following error Uncaught Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement in React Hooks in reactjs. So Here I am Explain to you all the possible solutions here.

Uncaught Error: Rendered fewer hooks than expected.This may be caused by an accidental early
return statement.
at invariant(react - dom.development.js: 55)
at finishHooks(react - dom.development.js: 11581)
at updateFunctionComponent(react - dom.development.js: 14262)
at beginWork(react - dom.development.js: 15103)
at performUnitOfWork(react - dom.development.js: 17817)
at workLoop(react - dom.development.js: 17857)
at HTMLUnknownElement.callCallback(react - dom.development.js: 149)
at Object.invokeGuardedCallbackDev(react - dom.development.js: 199)
at invokeGuardedCallback(react - dom.development.js: 256)
at replayUnitOfWork(react - dom.development.js: 17113)
at renderRoot(react - dom.development.js: 17957)
at performWorkOnRoot(react - dom.development.js: 18808)
at performWork(react - dom.development.js: 18716)
at flushInteractiveUpdates$1(react - dom.development.js: 18987)
at batchedUpdates(react - dom.development.js: 2210)
at dispatchEvent(react - dom.development.js: 4946)
at interactiveUpdates$1(react - dom.development.js: 18974)
at interactiveUpdates(react - dom.development.js: 2217)
at dispatchInteractiveEvent(react - dom.development.js: 4923)
load more v
23%

Ask questions“Rendered fewer hooks than expected” fired in an error boundary component without hooks ,I’ve seen the “rendered fewer hooks than expected” invariant a couple times now pointing at a component rendered as a part of an error boundary that just caught an error when that component does not use hooks at all.,I’ve been able to fix this issue by un-commenting:

I ran into the issue again and was able to produce a small repro: https://codesandbox.io/s/intelligent-cannon-f6bqx

import React, { useState, useEffect } from "react";
import { render } from "react-dom";

function App() {
  return (
    <ErrorBoundary>
      <Thrower />
    </ErrorBoundary>
  );
}

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  render() {
    return (
      <Wrapper>{this.state.hasError ? null : this.props.children}</Wrapper>
    );
  }
}

function Thrower() {
  const [shouldThrow, setShouldThrow] = useState(false);

  if (shouldThrow) {
    throw new Error("Throw!");
  }

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

  return <button onClick={() => setShouldThrow(true)}>Throw!</button>;
}

function Wrapper({ children }) {
  return children;
}

render(<App />, document.getElementById("root"));
load more v

Other "hooks-react" queries related to "React JS: Rendered fewer hooks than expected. This may be caused by an accidental early return statement"