我有一个customHook,我需要在两个地方调用它。一个在组件的顶层。另一个地方是按钮的onclick函数,此按钮是刷新按钮,它调用customHook来获取新数据,如下所示。我在想两种方法:
为数据创建状态,调用挂钩并在组件中设置数据状态,在onclick函数中,调用挂钩并设置数据状态。但是,无法在另一个函数(即onclick)中调用该钩子。
创建一个称为触发的布尔状态,每次单击按钮时,切换触发状态并将触发状态传递到从属列表的myCallback中,以便重新创建myCallback函数,并调用该挂钩。但是,我实际上并不需要在回调函数中使用此触发状态,并且该挂钩给了我删除不必要的依赖项的错误。我真的很喜欢这个主意,但是有办法解决这个问题吗?
还是有其他方法可以实现目标?
const MyComponent = () => {
const myCallback = React.useCallback(() => { /*some post processing of the data*/ }, []);
const data = customHook(myCallback);
return <SomeComponent data={data}>
<button onclick={/*???*/}></button>
</SomeComponent>;
};
答案 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函数() => {}
-应该可以使短毛绒陷入困境。