-
高阶组件 HOC
- 优点
- 外层组件通过 props 影响内部组件状态,而不是通过改变其 state 存在冲突和干扰,降低耦合度;
- 缺点
- 无法从外部访问子组件的 state,因此无法通过 shouldComponentUpdate 过滤不必要的更新(后来通过 React.PureComponent 解决);
- ref 传递问题:ref 被隔断(可通过 React.forwardRef 解决);
- 命名冲突: 嵌套过深的组件之间的 prop 容易产生命名冲突;
-
示例代码
function higherOrderComponent(WrappedComponent) { class CommonComponent extends React.Component { /* ... */ render(){ return <WrappedComponent /> } } return CommonComponent; } const EnhancedComponent = higherOrderComponent(WrappedComponent);
- 优点
-
渲染属性 render props
- 优点
- 解决了 HOC 上面的缺点;
- 缺点
- 使用繁琐: HOC 使用可借助装饰器语法通常一行代码进行复用,render props 必须通过函数;
- 容易造成函数回调嵌套;
- 示例代码
class A extends React.Component{ return ( <> {this.props.render(this.state.C)} </> ) } class B extends React.component{ return <A render={(para)=>{ return <div>{para}</div> }} /> } - 优点
-
react-hooks
- 优点
- 简洁:解决了 HOC 和 render props 的嵌套问题
- 解耦:UI 和状态分离
- 组合: hooks 中可以引另外的 hooks
- 函数友好:函数组件解决了类组件的几大问题
- this 指向容易错误
- 分布在不同生命周期中的逻辑较分散
- 高阶组件易使代码量剧增
- 缺点
- 学习成本较高
- 写法限制:不能出现在条件、循环中
- 破坏了 PureComponent、React.memo 浅比较的性能优化效果(为了获取最新的 prop 和 state,每次 render 都要重新创建事件处理函数)
- 内部黑盒,对外部不可见
- React.memo 不能完全代替 shouldComponentUpdate(因为拿不到 state change,只针对 props change)
-
示例代码
function useHttp(url,dependecies){ let [loaded,setLoaded] = useState(false); let [data,setData] = useState({}) useEffect(()=>{ _fetch(url) },dependecies) const _fetch = async (url) => { let res = await api.fetch(url); setLoaded(true); setData(res.data) } return [loaded, data] } function A(){ let [loaded, data] = useHttp('api.com/demo',selectedTarget) return <>{data}</> }
- 优点