使用useEffect常见问题!

如何用useEffect模拟componentDidMount生命周期?

虽然可以使用 useEffect(fn, []),但它们并不完全相等。和 componentDidMount 不一样,useEffect 会捕获 propsstate。所以即便在回调函数里,你拿到的还是初始的 propsstate。如果你想得到“最新”的值,你可以使用 ref。不过,通常会有更简单的实现方式,所以你并不一定要用 ref

如何正确地在useEffect里请求数据?[]又是什么?

下片篇文章介绍了如何在useEffect里做数据请求。[] 表示 effect 没有使用任何React数据流里的值,因此该 effect 仅被调用一次是安全的。[] 同样也是一类常见问题的来源,即使你以为没使用数据流里的值,但其实使用了。你需要学习一些策略(主要是useReduceruseCallback)来移除这些 effect 依赖。

我应该把函数当做effect的依赖吗?

一般建议把不依赖 propsstate 的函数提到你的组件外面,并且把那些仅被 effect 使用的函数放到 effect 里面。如果这样做了以后,你的 effect 还是需要用到组件内的函数(包括通过props传进来的函数),可以在定义它们的地方用useCallback 包一层。为什么要这样做呢?因为这些函数可以访问到propsstate,因此它们会参与到数据流中。

为什么有时候会出现无限重复请求的问题?

这个通常发生于你在 effect 里做数据请求并且没有设置 effect 依赖参数的情况。没有设置依赖,effect 会在每次渲染后执行一次,然后在 effect 中更新了状态引起渲染并再次触发 effect。无限循环的发生也可能是因为你设置的依赖总是会改变。你可以通过一个一个移除的方式排查出哪个依赖导致了问题。但是,移除你使用的依赖(或者盲目地使用[])通常是一种错误的解决方式。你应该做的是解决问题的根源。举个例子,函数可能会导致这个问题,你可以把它们放到effect里,或者提到组件外面,或者用 useCallback 包一层。useMemo 可以做类似的事情以避免重复生成对象。

为什么有时候在effect里拿到的是旧的state或prop呢?

Effect拿到的总是定义它的那次渲染中的propsstate。这能够避免一些bugs,但在一些场景中又会有些讨人嫌。对于这些场景,你可以明确地使用可变的ref保存一些值。如果你觉得在渲染中拿到了一些旧的props和state,且不是你想要的,你很可能遗漏了一些依赖。