如何创建一个接收依赖项的自定义钩子?

Posted

技术标签:

【中文标题】如何创建一个接收依赖项的自定义钩子?【英文标题】:How to create a custom hook that recives dependencies? 【发布时间】:2020-02-01 06:33:45 【问题描述】:

我正在制作一个自定义钩子,当某些状态发生变化时会有一个工具。

您应该能够传递数组中的任何状态。

import  useState, useEffect  from 'react'

const useFlatListUpdate = (dependencies = []) => 
    const [toggle, setToggle] = useState(false)

    useEffect(() => 
        setToggle(t => !t)
    , [...dependencies])

    return toggle


export default useFlatListUpdate

它应该被用作

const toggleFlatList = useFlatListUpdate([search, selectedField /*, anything */])

但它给了我以下警告

React Hook useEffect 在其依赖数组中有一个展开元素。这意味着我们无法静态验证您是否传递了正确的 dependencies.eslint(react-hooks/exhaustive-deps)

我还有另一种情况,它不起作用

const useFlatListUpdate = (dependencies = []) => 
    const [toggle, setToggle] = useState(false)

    useEffect(() => 
        setToggle(t => !t)
    , dependencies)

    return toggle

这给了我警告

React Hook useEffect 传递了一个不是数组文字的依赖项列表。这意味着我们无法静态验证您是否传递了正确的 dependencies.eslint(react-hooks/exhaustive-deps)

如何在没有警告且不禁用 eslint 的情况下完成这项工作?

【问题讨论】:

你是对的。我的回答是大错特错。我删除了它,以免进一步混淆您和其他人。我道歉???? @dance2die 你的回答没有错,但它只是给出了另一种警告。 感谢您的客气话。我也无法让它与裁判一起工作,所以我会把这件事留给其他人:) 对于第二个示例,只需将依赖项放入数组中:useEffect(() => setToggle(t => !t) , [dependencies]) 【参考方案1】:

在第一种情况下,您被要求避免数组传播, 所以你应该把dependancyList作为一个整体传递:

    useEffect(() => 
        setToggle(t => !t)
    , dependencies)

下一个警告说您错过了一个依赖项 (setToggle)。

您可以将useCallback 与内部效果依赖项一起使用,然后使用钩子用户提供的依赖项将其包装在 useEffect 中:

import  useCallback, useState, useEffect  from 'react'

const useFlatListUpdate = (dependencies = []) => 
    const [toggle, setToggle] = useState(false)

    useCallback(() =>  setToggle(t => !t) , [setToggle])
    useEffect(toggleEffect, dependencies])

    return toggle


export default useFlatListUpdate

【讨论】:

setToggle 不需要包含在 useCallback 中【参考方案2】:

您真的需要根据问题创建自定义挂钩吗?

您可以使用useEffect 检查您的依赖项是否已更改,如果更改,请在您的组件中设置类似这样的切换。

const [toggle, setToggle] = useState(false);
useEffect(() =>
  setToggle(!toggle);
, [yourDepndency]);

帮助我了解我是否正确理解了您的要求。

【讨论】:

【参考方案3】:

在这种情况下,依赖列表的使用非常特殊。 除了忽略或消除警告外,我没有看到其他方法。

要使警告静音,我们不必完全禁用 eslint。 您可以为此特定行禁用此特定规则:

const useFlatListUpdate = (dependencies = []) => 
    const [toggle, setToggle] = useState(false)

    /* eslint-disable react-hooks/exhaustive-deps */
    useEffect(() => 
        setToggle(t => !t)
    , [...dependencies])

    return toggle

【讨论】:

以上是关于如何创建一个接收依赖项的自定义钩子?的主要内容,如果未能解决你的问题,请参考以下文章

我应该在这个包装 useSWR 的自定义钩子中测试啥?

Prestashop 1.7 中的自定义钩子

为啥 jest 不能为我正在测试的自定义 React 钩子提供 useTranslation 钩子?

vue3的自定义指令

vue3的自定义指令

vue3的自定义指令