指示道具的最佳实践用于useEffect或类似情况



在React+Typescript中编写组件时,我经常想在其中一个道具上触发useEffect钩子。例如,考虑一个按钮,它为每次连续的鼠标点击执行不同的功能:

export function ActionButton({clickActions}: {clickActions: (() => void)[]}) {
const [clicked, setClicked] = useState(0);
useEffect(() => {
if (clickActions.length > 0 && clickActions[clicked % clickActions.length]) {
clickActions[clicked % clickActions.length]();
}
}, [clicked, clickActions])
return <button onClick={() => setClicked(clicked => clicked + 1)}/>
}

在这种情况下,该组件的客户端需要意识到,他们需要以某种方式防止clickActions在每次渲染中成为不同的实例。例如,它可以简单地是一个常数,也可以使用useMemo进行记忆。

有没有让我的客户意识到这一点的最佳实践?当违反此规则时,是否有方法触发编译时错误?

注意:我意识到这个特殊情况可以在不使用useEffect的情况下解决,但这只是一个简单的示例来说明模式。我对解决这个特定问题不感兴趣,而是对如何解决一般问题感兴趣。

您无法通过TypeScript技巧强制执行clickActions不能在每次父级渲染时更改。

但是,您可以简单地从useEffect的依赖项列表中删除clickActions。通常,在执行此操作时必须小心,但在这种情况下,这是安全的,因为当clicked发生更改时,同步传递给useEffect的回调将执行一个操作,这意味着回调将在需要时引用最新的clickActions

这类似于RxJS中的sample运算符;即CCD_ 11由CCD_。

useEffect(() => {
if (clickActions.length > 0 && clickActions[clicked % clickActions.length]) {
clickActions[clicked]();
}
}, [clicked])

还请注意,即使父级使用useMemo,也不能保证在React选择时不会重新创建clickActions

您可以将useMemo作为性能优化,而不是语义保证将来,React可能会选择"忘记"一些以前存储的值,并在下次渲染时重新计算它们,例如为屏幕外组件释放内存。编写代码,使其在没有useMemo的情况下仍然可以工作,然后添加它以优化性能。

(请参阅useMemo文档(

可以肯定地假设useCallback也有类似的警告,尽管文档中没有特别提到。

通常情况下,如果您有一个函数正在传递其重要性(特别是如果它在函数中"created"(,则在创建它时使用useCallback;道具不变"从而防止重新应答。

parentFunction = useCallback(()=>{
if (specialVar==='dance'){
return () => {
console.log('dance')
}
}
else {
return () => {
console.log('do the boogy')
}
}
}, [specialVar])

相关内容

  • 没有找到相关文章

最新更新