React hooks in Gatsby: Invalid hook call

14,919

Your import in usePrevious hooks file is incorrect. useRef and useEffect should be import from 'react' and not React;

import { useRef, useEffect} from "react"
Share:
14,919
Björn Hjorth
Author by

Björn Hjorth

Updated on June 09, 2022

Comments

  • Björn Hjorth
    Björn Hjorth almost 2 years

    Trying to implement a custom hook from a react example: https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state, but I get the following error:

    ERROR:

    Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
    1. You might have mismatching versions of React and the renderer (such as React DOM)
    2. You might be breaking the Rules of Hooks
    3. You might have more than one copy of React in the same app
    

    The error happen on useEffect when I try to import it as a custom hook usePrevious.

    I tried following: verified that react-dom and react is on the same version [email protected] [email protected]

    Verfied I only have one version of React

    Also I do belive the code is not breaking any rules of hooks.

    Also tried looking at related issues here on stackoverflow.

    CODE:

    // file: use-previous.js
    
    import { useRef, useEffect} from "React"
    
    export const usePrevious = (value) =>  {
    
        const ref = useRef();
        useEffect(() => {
          ref.current = value;
        });
    
    
    
    
        return ref.current;
    }
    
    // file: layout.js
    
    import React, { useState, useEffect } from "react"
    
    import Header from "./header/header"
    
    import { useFacetsData } from "../hooks/use-facets-data"
    import { usePrevious } from "../hooks/use-previous"
    
    
    export default ({ children, ...props }) => {
    
        const [ searchValue, setSearchValue ] = useState("")
    
        const [ facetsSelected, setFacetsSelected ] = useState([])
    
        const facets = useFacetsData()
    
    
        const oldSearchValue = usePrevious(searchValue)
        // const oldFacetsSelected = usePrevious(facetsSelected)
    
        useEffect(() => {
            // if new searchvalue or new facetvalue
    
            // if (searchValue !== oldSearchValue || facetsSelected !== oldFacetsSelected) makeSearch()
        }) 
    
        function makeSearch() {
            console.log('make search')
    
            // move to searchpage 
        }
    
        function handleSearchChange(search) {
            setSearchValue(search)
        }
    
        function handleFacetChange(facets) {
            setFacetsSelected(facets)
        }   
    
        return   (
            <div>
                {/* Main sticky header */}
                <Header 
                    facets={ facets } 
                    onSearchChange={ handleSearchChange } 
                    onFacetChange={ handleFacetChange } >
                </Header>
    
                {/* route content */}
               {React.cloneElement(children, { facets })}
            </div>
        )
    }