reactjs - 在 useEffect 或类似中使用指示 prop 的最佳实践

标签 reactjs typescript react-hooks

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

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每次父级渲染时都无法更改。
但是,您可以简单地删除 clickActions来自 useEffect的依赖列表。一般来说,这样做时你必须小心,但在这种情况下,它是安全的,因为你传递给 useEffect 的回调clicked 时同步执行一个 Action 更改,这意味着回调将引用最近的 clickActions当它需要它时。
这类似于 sample RxJS 中的运算符;即clickActionsclicked 采样.

useEffect(() => {
  if (clickActions.length > 0 && clickActions[clicked % clickActions.length]) {
    clickActions[clicked]();
  }
}, [clicked])
另请注意,即使 parent 使用 useMemo , 不保证不会重新创建 clickActions在 React 选择的时候:

You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.


(见 useMemo docs)
可以肯定地假设 useCallback带有类似的警告,尽管文档中没有特别提及。

关于reactjs - 在 useEffect 或类似中使用指示 prop 的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63314762/

相关文章:

javascript - React 路由器问题未捕获错误 : Invariant Violation: Element type is invalid: expected a string (for built-in components)

javascript - React 中 <tr> 元素上的 anchor 标记行为

reactjs - react 钩子(Hook) : Is there a way to calculate state values based on another state value

javascript - 使用 Material Angular 10 的格式更改 Datepicker 的语言

typescript - 如何根据参数类型转换函数的返回类型?

javascript - React Hooks setState 的意外结果

reactjs - React Router 6.3.0 渲染组件两次

javascript - 登录 React-Redux 后无法重定向

javascript - 无法使用 setstate Hook 复制数组

typescript - 如何将 import all 与其他的结合起来?