React用空依赖useEffect模拟componentDidMount出现依赖警告怎么办?
空依赖useEffect模拟componentDidMount出现依赖警告的解决方案
问题本质
空依赖数组的useEffect和类组件的componentDidMount并非完全等价:
componentDidMount仅在组件首次挂载后执行一次,读取的永远是当前最新的类实例属性,包括最新的props、state值- 空依赖的
useEffect回调仅在组件首次挂载时创建一次,会捕获当时的闭包环境,内部访问的props、state永远是首次渲染时的旧值,即使后续属性更新也不会同步。react-hooks/exhaustive-deps规则抛出警告,正是为了避免你误用到过期的闭包值。
可选解决方案
方案一:仅需要读取首次挂载时的props值
如果你确定不需要响应后续props更新,只需要拿到组件刚挂载时的props值,可以直接禁用对应lint规则:
useEffect(() => { console.log(props.myProp1) console.log(props.myProp2) console.log('DIDMOUNT.'); // eslint-disable-next-line react-hooks/exhaustive-deps }, [])
这是最简便的处理方式,完全符合只执行一次的需求,属于官方认可的合理用法。
方案二:需要和类组件componentDidMount行为完全对齐,读取最新props值
如果你需要effect执行时拿到当前最新的props值,同时保证effect只执行一次,可以用ref存储最新的props:
import { useEffect, useRef } from 'react'; // 用ref存储最新的props值,ref更新不会触发组件重渲染 const latestPropsRef = useRef(props); useEffect(() => { latestPropsRef.current = props; }); // 空依赖effect仅执行一次,读取ref.current即可拿到最新props useEffect(() => { console.log(latestPropsRef.current.myProp1) console.log(latestPropsRef.current.myProp2) console.log('DIDMOUNT.'); }, [])
这种方案完全对齐类组件componentDidMount的行为,不会读到过期的闭包值,也不会触发effect重复执行。
内容的提问来源于stack exchange,提问作者joedotnot
相关产品推荐
相关产品推荐

