Die*_*sel 10 typescript reactjs react-hooks
对此还有其他几个 SO 问题,答案是通过 ESLint(我正在使用打字稿)消除依赖项投诉,或者做其他事情以仍然允许 useEffect 的第二个参数为[]. 但是,根据 React文档,不建议这样做。同样在反应 useEffect 文档下它说
如果传递一个空数组 ([]),则效果中的 props 和 state 将始终具有其初始值。虽然传递 [] 作为第二个参数更接近熟悉的 componentDidMount 和 componentWillUnmount 心智模型,但通常有更好的解决方案来避免过于频繁地重新运行效果。另外,不要忘记 React 将 useEffect 的运行推迟到浏览器绘制完成之后,所以做额外的工作不是问题。
我有以下代码:
useEffect(() => {
container.current = new VisTimeline(container.current, items, groups, options);
}, [groups, items, options]);
Run Code Online (Sandbox Code Playgroud)
我希望它只运行一次。
是让它每次运行并useState跟踪它之前运行过的唯一方法:
const [didLoad, setDidLoad] = useState<boolean>(false);
useEffect(() => {
if (!didLoad) {
container.current = new VisTimeline(container.current, items, groups, options);
setDidLoad(true);
}
}, [didLoad, groups, items, options]);
Run Code Online (Sandbox Code Playgroud)
我现在处理这个问题的方法是将适当的依赖项放在依赖项列表中。
因为我希望效果只运行一次,并且因为该效果只在组件第一次挂载时依赖于一些数据,所以省略这些依赖关系是完全没问题的。例如,groups道具可能会在稍后更改,但此效果不需要再次运行。
但是,作为一种习惯,我不会省略推荐的依赖项,我总是列出它们。如果我故意省略某些内容,我会添加一个 eslint ignore 语句(尽管还没有遇到需要这样做的情况)……只要您了解数据更改时发生的情况,这就是您想要遵循的任何约定并且效果确实/不运行。
但是,如果您确实想列出依赖项,我提出的代码也不是最佳解决方案:
const [didLoad, setDidLoad] = useState<boolean>(false);
useEffect(() => {
if (!didLoad) {
container.current = new VisTimeline(container.current, items, groups, options);
setDidLoad(true);
}
}, [didLoad, groups, items, options]);
Run Code Online (Sandbox Code Playgroud)
当此效果运行时,我不想引起渲染。因此,我将使用 ref(不需要是依赖项)而不是使用状态。
const timelineLoaded = useRef<boolean>(false);
useEffect(() => {
if (!timelineLoaded.current) {
container.current = new VisTimeline(container.current, items, groups, options);
timelineLoaded.current = true;
}
}, [groups, items, options]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10290 次 |
| 最近记录: |