在回调函数中使用自定义钩子

时间:2020-11-11 06:36:52

标签: reactjs react-hooks

我有一个customHook,我需要在两个地方调用它。一个在组件的顶层。另一个地方是按钮的onclick函数,此按钮是刷新按钮,它调用customHook来获取新数据,如下所示。我在想两种方法:

  1. 为数据创建状态,调用挂钩并在组件中设置数据状态,在onclick函数中,调用挂钩并设置数据状态。但是,无法在另一个函数(即onclick)中调用该钩子。

  2. 创建一个称为触发的布尔状态,每次单击按钮时,切换触发状态并将触发状态传递到从属列表的myCallback中,以便重新创建myCallback函数,并调用该挂钩。但是,我实际上并不需要在回调函数中使用此触发状态,并且该挂钩给了我删除不必要的依赖项的错误。我真的很喜欢这个主意,但是有办法解决这个问题吗?

  3. 还是有其他方法可以实现目标?

    const MyComponent = () => {  
         const myCallback = React.useCallback(() => { /*some post processing of the data*/ }, []);  
         const data = customHook(myCallback);  
    
         return <SomeComponent data={data}>
                     <button onclick={/*???*/}></button>
                 </SomeComponent>; 
     };
    

1 个答案:

答案 0 :(得分:1)

可以通过一些调整使第二个示例工作。不必传入依赖关系来更新effect函数,只需使effect函数成为传递给useEffect的独立函数,但也可以在其他地方调用(例如,您可以从钩子中返回effect函数,以便您的钩子用户也可以使用)

例如:

const App = () => {
  const { resource, refreshResource } = useResource()
  return (
    <div>
      <button onClick={refreshResource}>Refresh</button>
      {resource || 'Loading...'}
    </div>
  )
}

const useResource = () => {
  const [resource, setResource] = useState(null)
  const refreshResource = async () => {
    setResource(null)
    setResource(await fetchResource())
  }
  useEffect(refreshResource, [])
  return { resource, refreshResource }
}

const fetchResource = async () => {
  await new Promise(resolve => setTimeout(resolve, 500))
  return Math.random()
}

修改

我还没有意识到钩子无法编辑。老实说,我想不出任何解决您问题的好方法-也许不存在。理想情况下,提供此自定义挂钩的API还将提供一些较低级别的绑定,您可以使用这些绑定来解决此问题。

如果最糟糕的情况变得更糟,并且您必须继续采取一些棘手的解决方案,那么更新回调的解决方案#2应该可以工作(假设自定义钩子在参数更改时重新获取资源)。您只需要解决掉毛规则,如果使用eslint,我敢肯定您可以在引起问题的行上添加/* eslint-disable-line */注释。最糟糕的是,您可以创建一个使用触发参数调用的noop函数() => {}-应该可以使短毛绒陷入困境。