很多Vue转React的同学在刚开始的时候可能对于后者最不适应的一点是,每当states或者props产生变化时,render函数是会重新run一遍的。而父组件的重新渲染,在默认的情况下,也会触发子组件的重新渲染。这个特性就使得React同学会经常需要用到的useMemo, useCallback这样的优化手段以减少不必要re-render。关于这点,掘金已经有很多优秀的文章介绍这一点了:
详解 React useCallback & useMemo
虽然官方提供了很好的支持,但是这些主要用作性能优化的代码其实会加大对于组件内业务逻辑理解的难度,降低代码可读性。另外对于新人来说,往往很难掌握好用还是不用这些优化手段的边界,甚至在所有的组件里强行使用useMemo和useCallback,过多的优化也会带来出现问题难于debug的情况。
在前段时间举行的React Conf 21中,来自Facebook工程师黄玄 (现在都自我介绍是来自Meta了 😓)做了一次名为 React without Memo的演讲(视频来自油管,可以参考机翻中文字幕),解释了React Team在做Research的一个项目,也旨在解决上面的问题和提高开发者体验。其大致原理是在React组件编译时刻(complier time),在组件内部实现一些监听prop和state变化的flag,只有在他们产生变化的时候再去重新run render函数的主体并生成新的JSX。在这种情况下,如果是这样的开发代码:
functiion Component ({color}) {
let [count, setCount] = useState(0)
return <div style={{color: color}}>{count}</div>
}
会被编译器改为
functiion Component ({color}) {
let [count, setCount] = useState(0)
if (isCountChanged || isColorChanged) {
return <div style={{color: color}}>{count}</div>
} else {
return lastRenderOutput
}
}
当然这些只是示意代码,真正转译的结果会比这个复杂的多。这样一来开发者只用专注于自身业务代码,而将优化的工作交给编译器。希望React Team能早日完成这个feature比交给社区使用吧。
PS 尤大还在推上夸黄玄来着