简体   繁体   English

在回调中使用自定义钩子 function

[英]Use custom hook in callback function

I have a customHook, and I need to call it in two places.我有一个customHook,我需要在两个地方调用它。 One is in the top level of the component.一个在组件的顶层。 The other place is in a onclick function of a button, this button is a refresh button which calls the customHook to fetch new data like below.另一个地方是在一个 onclick function 的一个按钮,这个按钮是一个刷新按钮,它调用 customHook 来获取新的数据,如下所示。 I am thinking of two approaches:我正在考虑两种方法:

  1. create a state for the data, call hook and set the data state in the component and in the onclick function, call hook and set the data state. However, the hook cannot be called inside another function ie onclick in this case.为数据创建一个state,调用hook并在组件中设置数据state,在onclick function中调用hook并设置数据state。但是,在另一个88340040158888983中调用hook并设置数据。

  2. create a boolean state called trigger, everytime onclick of the button, toggle the trigger state and pass the trigger state into the myCallback in the dependent list so that myCallback function gets recreated, and the hook gets called.创建一个 boolean state 调用触发器,每次 onclick 按钮,切换触发器 state 并将触发器 state 传递到从属列表中的 myCallback,以便重新调用 myCallback 883400406589,88 钩子However, I don't really need to use this trigger state inside the callback function, and the hook gives me error of removing unnecessary dependency.但是,我真的不需要在回调 function 中使用这个触发器 state,并且挂钩给我错误删除不必要的依赖项。 I really like this idea, but is there a way to overcome this issue?我真的很喜欢这个想法,但是有没有办法解决这个问题?

  3. Or is there any other approaches to achieve the goal?还是有其他方法可以实现目标?

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

It is possible to make your second example work with some tweaking.可以通过一些调整使您的第二个示例工作。 Instead of passing in a dependency to update the effect function, just make the effect function a stand-alone function that you pass into useEffect, but can also call in other places (eg you can return the effect function from your hook so your hook users can use it too)不要传入依赖项来更新效果 function,只需使效果 function 成为一个独立的 function,您将其传递给 useEffect,但也可以在其他地方调用(例如,您可以从钩子中返回效果 function,这样您就可以钩住用户也可以用)

For example:例如:

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

Edit编辑

I hadn't realized that the hook couldn't be edited.我没有意识到无法编辑挂钩。 I honestly can't think of any good solutions to your problem - maybe one doesn't exist.老实说,我想不出任何好的解决方案来解决您的问题 - 也许不存在。 Ideally, the API providing this custom hook would also provide some lower-level bindings that you could use to get around this issue.理想情况下,提供此自定义挂钩的 API 还将提供一些较低级别的绑定,您可以使用它们来解决此问题。

If worst comes to worst and you have to proceed with some hackish solution, your solution #2 of updating the callback should work (assuming the custom hook refetches the resource whenever the parameter changes).如果最坏情况变得更糟,并且您必须继续使用一些 hackish 解决方案,那么更新回调的解决方案 #2 应该可以工作(假设自定义挂钩在参数更改时重新获取资源)。 You just have to get around the linting rule, which, I'm pretty sure you can do with an /* eslint-disable-line */ comment on the line causing the issue, if eslint is being used.你只需要绕过 linting 规则,我很确定你可以在导致问题的行上使用/* eslint-disable-line */注释,如果正在使用 eslint。 Worst comes to worst, you can make a noop function () => {} that you call with your trigger parameter - that should put the linter at bay.最坏的情况是,您可以使用触发参数调用 noop function () => {} - 这应该会阻止 linter。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM