Search code examples
reactjstypeerroruse-effect

useEffect() TypeError: e is not a function


I'm getting TypeError: e is not a function

at MessagePort.C.port1.onmessage (react.production.min.js:24)

for reasons that I do not understand in a useEffect(). I realize this is probably an obscure problem relative to my codebase seeing as I cannot replicate in codesandbox but figured I'd throw this up anyhow.

useEffect(() => someVar && console.log('asdf'), [button])

It seems to work when I simply put the function in a block

useEffect(() => {if (someVar) console.log('asdf')}, [button])

Solution

  • My first assumption is that you are not really meaning to return from the useEffect, but were mis-using the short hand syntax and didn't realize it uses an implicit return (read here about arrow functions and implicit returns).

    The returned function from useEffect will run as a cleanup (as mentioned in the comments). What you are returning from the effect will depend on the condition, but in neither case will it return a function. If someVar is falsy it will return someVar. If someVar is truthy, it will return the value of console.log() which is undefined.

    See below what happens when a useEffect returns false (click the "unmount" button to see the effect).

    const {useState, useEffect} = React;
    
    const Example = () => {
      const [toggle, setToggle] = useState(true);
       
       return (
        <div>
          {toggle ? <Child /> : null}
          <button onClick={() => setToggle(!toggle)}>unmount</button>
        </div>)
    }
    const Child = () => {
       useEffect(() => false);
       
       return <span />
    }
    
    
    ReactDOM.render(<Example />, document.getElementById('root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    You should always use the long hand form of an arrow function when using an effect, unless you only intend to pass it a cleanup.