3 最佳实践
3. 最佳实践
3.1 Class组件 vs 函数式组件
首选函数式组件,因为它们有着更简单的语法,没有生命周期、构造函数等,可以用更简洁的代码来表达相同的逻辑,同时拥有更好的可读性。
3.2 Hooks
3.2.1 使用 useMemo/useCallback
useCallback 和 useMemo 结合 React.Memo 方法的使用是常见的性能优化方式,可以避免由于父组件状态变更导致不必要的子组件进行重新渲染。
3.2.2 useMemo
可以使用 useMemo 缓存一些相对耗时的计算,除此以外,useMemo 也非常适合用于存储引用类型的数据,可以传入对象字面量,匿名函数等,甚至是 React Elements。
对于组件返回的 React Elements,我们可以选择性地提取其中一部分 elements,通过 useMemo 进行缓存,也能避免这一部分的重复渲染。
但是当返回的是原始数据类型(如字符串、数字、布尔值)。即使参与了计算,只要 deps 依赖的内容不变,返回结果也很可能是不变的。此时就需要权衡这个计算的时间成本和 useMemo 额外带来的空间成本(缓存上一次的结果)了。
3.2.2 useContext
调用了 useContext 的组件都会在 context 值变化时重新渲染,为了减少重新渲染组件的较大开销,可以通过拆分不会一起更改的 context 或者使用 memoization 来优化。
3.3 路由
推荐使用 React Router
3.4 样式/CSS
CSS-in-CSS 方案: CSS Modules
CSS-in-JS 方案: Styled Components (推荐)
函数式 CSS:Tailwind CSS
备选:CSS 类的条件渲染:clsx
3.5 状态管理
用 useState/useReducer 处理共享状态
选择性使用 useContext 管理某些全局状态
如果需要更强大的状态管理工具,推荐使用 Mobx + Mobx-react
3.6 数据结构
Vanilla JavaScript 本身提供了大量内置工具来处理数据结构,如果需要使用不可变数据结构,推荐使用Immer。
3.7 传递对象而不是基础数据
限制props数量的一种方法是传递一个对象而不是基础数据。可以将它们组合在一起,而不是作为基础数据一一传递。
// bad 如果值都是相关的,不用一个一个传递
<UserProfile
bio={user.bio}
name={user.name}
email={user.email}
subscription={user.subscription}
/>
// good 使用对象进行传递,在后期增改字段也更方便
<UserProfile user={user} />
**