Open wangsiyuan0215 opened 5 years ago
期待:不论传递组件的属性如何变化,组件都可以将其变化反映出来。
initialValue
defaultValue
解决方案是使用 memoized-one 或者是 React Hook —— useMemo。
memoized-one
useMemo
解决方案是使用 React Hook 的 useEffect API;
useEffect
可以使用 React.memo 或者是在 shouldComponentWillUpdate 中将 props 所有属性进行比较,或者使用 React.PureComponent 或者是通过 useCallback 和 useContext。
React.memo
shouldComponentWillUpdate
React.PureComponent
useCallback
useContext
不要试图在组件行为中,假设任何不必要的时序信息。你的组件应该随时可以重新渲染。
举个例子就是 TextInput 组件如果具有每次父节点渲染时重置本地状态的功能,那么这个功能完全依赖父组件的更新频率,如果父组件经常重新渲染的话,则可能会导致该组件总是在重置“自己的本地状态”。
TextInput
解决方案是编写完全受控的组件(functional component)或者是使用一个不受控(拥有本地状态)的组件,添加一个 key 来重置它(通过更改 key 的值来重置 TextInput 的内部状态)。
如果页面上有两个这样的组件,卸载其中一个组件可能会破坏另一个组件,这样的设计就是糟糕的设计。 显示或隐藏一颗树,不应该破坏树之外的组件。
如果页面上有两个这样的组件,卸载其中一个组件可能会破坏另一个组件,这样的设计就是糟糕的设计。
显示或隐藏一颗树,不应该破坏树之外的组件。
如果你不确定某个状态是否属于本地,请问自己:“如果此组件呈现两次,交互是否应反映在另一个副本中?” 只要答案为“否”,那你就找到本地状态了。 别把该本地的状态全局化了。
如果你不确定某个状态是否属于本地,请问自己:“如果此组件呈现两次,交互是否应反映在另一个副本中?” 只要答案为“否”,那你就找到本地状态了。
别把该本地的状态全局化了。
这篇文章,前两条原则具体地阐明了如何设计有弹性的组件,并且给予了平时编写组件时应该注意的地方和一些鉴别方法,后两条原则则是从整体的角度来进行阐述如何更好地保持组件的弹性(确定部分本地状态来互不影响)。
《编写有弹性的组件》
原则1:不阻断数据流
第一个误区:尽可能不要将 props 复制到 state,如果需要设置初始值或默认值,请在组件内部使用
initialValue
或者是defaultValue
。第二个误区:基于 props 进行昂贵计算,也不要将 props 复制到 state,若避免多次 render 时重新计算,推荐使用 memoization 方案来缓存结果。
第三个误区:不要在 Side Effects 里阻断数据流,使用 React Class 中的生命周期方法可以解决,不过很麻烦。
第四个误区:不要在优化中阻断数据流 (shouldComponentWillUpdate),不要只判断对象属性是否变化,还要考虑到组件的函数属性。
原则2:时刻准备渲染
举个例子就是
TextInput
组件如果具有每次父节点渲染时重置本地状态的功能,那么这个功能完全依赖父组件的更新频率,如果父组件经常重新渲染的话,则可能会导致该组件总是在重置“自己的本地状态”。原则3:没有单例组件
原则4:隔离本地状态
小结
这篇文章,前两条原则具体地阐明了如何设计有弹性的组件,并且给予了平时编写组件时应该注意的地方和一些鉴别方法,后两条原则则是从整体的角度来进行阐述如何更好地保持组件的弹性(确定部分本地状态来互不影响)。