React中无依赖useMemo对比useEffect:该场景为何选useMemo?
我是React新手,正在阅读React Navigation官方文档的认证流程章节,看到如下代码:
const authContext = React.useMemo( () => ({ signIn: async (data) => { dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' }); }, signOut: () => dispatch({ type: 'SIGN_OUT' }), signUp: async (data) => { dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' }); }, }), [] );
我不理解此处使用无依赖项useMemo的意义,认为用useEffect也能实现同样效果,想请教此场景下useMemo优于useEffect的原因是什么?
为什么这里用useMemo而不是useEffect?
1. 执行时机与同步性的本质差异
useMemo是同步执行的,组件渲染过程中就会生成authContext对象,渲染完成后这个值直接可用,不会出现“初始值为空,后续才赋值”的情况。- 换成
useEffect的话,它是组件渲染完毕后异步触发的,第一次渲染时authContext会是undefined(如果先声明变量再赋值),子组件拿到空值很可能触发报错或者额外的重渲染,逻辑完全不顺畅。
2. 避免不必要的重渲染
- 直接写
const authContext = { ... }的话,组件每次渲染都会生成新的对象引用,传给子组件时会触发子组件无意义的重渲染(React对比引用类型靠地址)。useMemo加空依赖能让这个对象在组件生命周期里只创建一次,彻底避免这种问题。 - 要是用
useEffect,你得配合useState来存这个对象:先声明const [authContext, setAuthContext] = useState(),再在useEffect里setAuthContext(...)。这样组件会先渲染一次(authContext为undefined),等useEffect执行完再渲染第二次,多了一次不必要的渲染,逻辑也更绕。
3. 语义化更贴合场景
useMemo的设计初衷就是缓存计算得出的结果,这里我们要缓存的就是包含三个方法的上下文对象,语义完全匹配。useEffect是用来处理副作用的(比如发请求、操作DOM、订阅事件),把生成纯对象的逻辑放在useEffect里属于误用,不符合React Hooks的设计逻辑。
内容的提问来源于stack exchange,提问作者yyhnfd
相关产品推荐
相关产品推荐

