useEffect 避免详尽警告的方法

Approach for useEffect to avoid exhaustive-dep warning

我一直 运行关注 exhaustive-dep 规则抱怨的情况。在下面的简单说明中,我想在 props.id 值更改时重置该值:

const TestComponent = props => {
  const [value, setValue] = useState(props.value);

  useEffect(() => {
    setValue(props.value);
  }, [props.id]);

  const saveValue = () => {
    props.save(value);
  }

  return <input value={value} onChange={e => setValue(e.target.value)} onBlur={saveValue} />;
};

但是,lint 规则希望我也将 props.value 添加到依赖项中。如果我这样做,它会有效地破坏组件,因为效果将 运行 每次更改输入并因此重置状态。

是否有 "right" 实现此行为的方法?

您编写组件的方式是半受控半不受控的风格,这很难做到。我建议要么完全控制,要么完全不受控制。

"controlled" 组件是仅作用于给定道具的组件。它从其 props 中获取值并将其转发给输入,没有状态。当输入发生变化时,它会调用 onChange 道具。当输入模糊时,它会调用 onBlur 道具。所有业务逻辑都由 parent 组件处理。

另一个选项是不受控制的组件,这主要是您拥有的组件。 parent 将传入一个属性作为初始值。我建议将它命名为 initialValue,这样很明显这只会被检查一次。之后,一切都由 child 组件管理。这意味着您的 useEffect 完全消失了:

const TestComponent = props = {
  const [value, setValue] = useState(props.initialValue);

  const saveValue = () => {
    props.save(value);
  }

  return <input value={value} onChange={e => setValue(e.target.value)} onBlur={saveValue} />;
}

那你怎么重置这个?同一个key。 parent 组件可以使用标准的 react key 来告诉 react 它应该卸载旧组件并安装一个新组件:

const ParentComponent = props = {
  // some code...
  return <TestComponent key={id} initialValue={"whatever"} />
}

只要 id 不变,TestComponent 就会执行它的操作,从传入的 initialValue 开始。当 id 更改时,TestComponent 卸载并安装一个新的,它将以给定的初始值。