React中用HOC包裹PureComponent能否仍避免不必要重渲染?
关于PureComponent被HOC包裹后是否仍能避免不必要重渲染的问题
嘿,这个问题问得很到位——很多人在结合HOC和PureComponent时都会有这个疑惑。先给你个明确的答案:是的,你的CachedImage组件依然能借助内部的PureComponent避免不必要的重渲染,但有几个关键细节得留意,不然可能让优化失效。
核心原因
你写的withCache是个常规HOC,它返回的函数组件Wrapped本身虽然不是PureComponent,但它内部渲染的那个继承了React.PureComponent的类组件,依然会发挥它的作用:每次接收到props时,会自动对新旧props做浅比较。如果props没有变化,它就不会触发重渲染(也就是你写的console.log("Rendering")不会执行)。
换句话说,HOC只是给你的PureComponent套了一层“外壳”,内部的PureComponent依然在兢兢业业地做重渲染判断,只要外壳传递给它的props是稳定的,优化效果就不会丢。
需要注意的几个坑
不过要是踩了下面这些坑,可能会让PureComponent的优化失效:
- 不要在组件内部定义HOC:如果你的
withCache是在某个父组件内部定义的,那每次父组件渲染时,都会重新创建Wrapped组件,这会导致内部的PureComponent被卸载再重新挂载——相当于每次都是全新的组件,自然谈不到重渲染优化。所以一定要把HOC定义在组件外部,保证它只创建一次Wrapped组件。 - 保证传递的props是稳定的:PureComponent的浅比较依赖于props的引用稳定性。如果你给
CachedImage传递的props里有每次渲染都会生成新引用的对象、数组或者函数(比如直接写style={{ width: 100 }}或者onPress={() => handleClick()}),PureComponent会认为props变了,触发不必要的重渲染。这种情况可以用useMemo缓存对象/数组,用useCallback缓存函数,或者把这些逻辑移到CachedImage内部处理。 - HOC不要传递不稳定的额外props:如果你的
withCache在传递props时,额外加了每次渲染都会变化的值(比如<Component {...props} key={Math.random()} />),那内部的PureComponent也会触发重渲染,直接破坏优化效果。
举个规范的HOC实现例子
比如你的withCache如果是这样写的,就不会有问题:
const withCache = (Component) => { // 给包裹组件起个有意义的名字,方便调试React DevTools const WrappedComponent = (props) => { // 用useMemo缓存处理后的缓存url,保证依赖不变时引用稳定 const cachedSource = useMemo(() => { return { uri: getCachedImageUrl(props.source.uri) }; }, [props.source.uri]); // 把稳定的props传递给内部的PureComponent return <Component {...props} source={cachedSource} />; }; WrappedComponent.displayName = `WithCache(${Component.displayName || Component.name})`; return WrappedComponent; };
这种情况下,只要props.source.uri不变,cachedSource的引用就不会变,内部的PureComponent就不会触发不必要的重渲染。
总的来说,只要你的HOC实现规范,没有破坏内部PureComponent的props稳定性,那它的重渲染优化就依然有效。
内容的提问来源于stack exchange,提问作者Raul
相关产品推荐
相关产品推荐

