React hooks在Gatsby中:无效的hook调用

6
尝试实现React示例中的自定义钩子: https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state ,但是我遇到了以下错误:

错误:

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

当我尝试将useEffect作为自定义钩子usePrevious导入时,出现了错误。

我尝试了以下步骤: - 确认react-dom和react版本相同:react-dom@16.8.5react@16.8.5 - 确认只有一个React版本存在 - 我相信代码没有违反任何hooks规则。 - 在stackoverflow上查看相关问题。

代码:

// 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>
    )
}


1
把这些值放到 useEffect 的依赖数组中,是否能达到同样的目的呢?就像这样 useEffect(() => ... , [searchValue, facetsSelected])。React 会自动比较数组中的值,如果检测到变化,effect 代码就会运行。 - Pavel Ye
@Powell_v2 对于 hooks 我还很新,所以这很有可能,我会检查一下。谢谢你的提示。 - Björn Hjorth
@Powell_v2 你说得对,对于其他有兴趣的人,这是它的文档:https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects - Björn Hjorth
1个回答

3

您在usePrevious hooks文件中的导入方式不正确。应该从'react'而不是React导入useRefuseEffect

import { useRef, useEffect} from "react"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接