关于React Context重渲染优化的疑问求助
关于React Context重渲染优化的疑问求助
嘿,我太懂你这种困惑了!当初刚摸React Context的时候,我也对着这段文档卡了好久,咱们慢慢捋清楚~
首先先明确你之前的认知:正常情况下,父组件重渲染确实会带动子组件重渲染;如果Context的Provider重渲染了,要是它的value发生了变化,那所有订阅这个Context的组件都会跟着重渲染。这部分你说的完全没错!
那文档里这句even if MyApp needs to re-render, the components calling useContext(AuthContext) won’t need to re-render到底是啥情况?核心在于Provider的value有没有保持引用稳定!
你想啊,要是你在MyApp里直接这么写:
function MyApp() { const [user, setUser] = useState(null); // 每次MyApp重渲染,这个对象都会被重新创建,引用变了! const authValue = { user, login: () => setUser('张三') }; return ( <AuthContext.Provider value={authValue}> {/* 订阅Context的子组件 */} </AuthContext.Provider> ); }
这时候MyApp重渲染,authValue是个新对象,React会认为Context的内容更新了,所以所有用useContext(AuthContext)的组件都会跟着重渲染。
但如果咱们用useMemo和useCallback把value的引用稳定住:
function MyApp() { const [user, setUser] = useState(null); // 用useCallback稳定函数引用,依赖不变就不重新创建 const login = useCallback(() => setUser('张三'), []); // 用useMemo稳定对象引用,只有依赖(user、login)变化时才更新 const authValue = useMemo(() => ({ user, login }), [user, login]); return ( <AuthContext.Provider value={authValue}> {/* 订阅Context的子组件 */} </AuthContext.Provider> ); }
这时候就算MyApp因为其他状态变化(比如和AuthContext无关的状态)重渲染,authValue的引用和之前完全一样(因为依赖没变化),React就会判断Context没有更新,那些订阅的组件自然就不用重渲染啦!
说白了,文档里的这句话是有前提的:你得通过useMemo/useCallback把Provider的value引用给稳住,不然父组件重渲染时value变了,订阅组件该重还是会重~
备注:内容来源于stack exchange,提问作者Leech
相关产品推荐
相关产品推荐

