Uncaught Invariant Violation: Rendered more hooks than during the previous render

Solution 1:

The fix works because the first code sample (the erroring one) invokes a function inside onClick, while the second (the working one) passes a function to onClick. The difference is those all-important parentheses, which in JavaScript mean 'invoke this code'.

Think of it this way: in the first code sample, every time component is rendered, renderResults is invoked. Every time that happens, setAllResultsVisible(!allResultsVisible), rather than waiting for a click, is called. Since React performs the render on its own schedule, there's no telling how many times that will happen.

From the React docs:

With JSX you pass a function as the event handler, rather than a string.

React Handling Events Docs

Note: I wasn't able to get this exact error message when running the first code sample in a sandbox. My error referred to an infinite loop. Maybe a more recent version of React produces the error described?

Solution 2:

I faced the same issue. What I was doing was something like this:

const Table = (listings) => {

    const {isLoading} = useSelector(state => state.tableReducer);

    if(isLoading){
        return <h1>Loading...</h1>
    }

    useEffect(() => {
       console.log("Run something")
    }, [])

    return (<table>{listings}</table>)
}

I think what was happening was that on the first render, the component returned early and the useEffect didn't run. When the isLoading state changed, the useEffect ran and I got the error - the hook rendered more times than the previous render.

A simple change fixed it:

const Table = (listings) => {
    
    const {isLoading} = useSelector(state => state.tableReducer);
        
    useEffect(() => {
        console.log("Run something")
    }, [])
    
    if(isLoading){
        return <h1>Loading...</h1>
    }
    return (<table>{listings}</table>)
}

Solution 3:

You can simply change your onlick event add () => before setAllResultsVisible

<p onClick={() => setAllResultsVisible(!allResultsVisible) }> 
    More results v
</p>

and it will work perfectly