Skip to content

Latest commit

 

History

History
106 lines (80 loc) · 3.34 KB

31.精读我不再使用高阶组件.md

File metadata and controls

106 lines (80 loc) · 3.34 KB

031.精读《我不再使用高阶组件》.md

函数作为 JS 的一等公民, 组件是 React 的一等公民,组件可以作为一个 props 向下传递,所以 React 具备了高度抽象化的能力

  • 高阶组件特点利用 JSX 描述的子元素,可以注入父级组件的this.props.children,可以入侵增强组件能力,如权限,跳转,埋点,异常,描述,注入等

困扰

  • 高阶组件如果内有将被包裹组件暴露出来,后续叠加的高阶组件都无法获取和注入到原始组件(wrappedComponent)

  • 解决思路 render props render callback function as child

    import React, {Component} from 'react';
    import PropTypes from 'prop-types';
    class Caffeinate extends Component {
    propTypes = {children: PropTypes.func.isRequired};
    state = {coffee: "Americano"};
    render() {
    return this.props.children(this.state.coffee)
    	}
    }
  • 直接将函数作为子函数,可认为是一个匿名组件

    render(
        <Caffeinate>
            {(beverage) => <div>Drinking an {beverage}</div>}
        </Caffeinate>,
        document.querySelector("#root")
    );

本质是组件作为参数

  • 通过 render()将 props 进行回传:

    import React, {Component} from 'react';
    import PropTypes from 'prop-types';
    class Caffeinate extends Component {
        propTypes = {children: Proptypes.func.isRequired};
    	state = {coffee: "Americano"};
    render() {
    	return this.props.child(this.state.coffee)
    	}
    }
    // usage
    	render(
        	<Caffeinate child={
                    {beverage} => <div>Drinking an {beverage}</div>
                }/>,
            document.querySelector("#root")
        )
  • render prop 利用props.children将参数写在 JSX 子元素中,嵌套写法可以看清楚数据流动,解决了高阶组件反复嵌套的各类问题

  • 对比高阶组件

    • HOC 相比,render props 开放性提升, 功能抽象可以通过 render props 获取,render 可以访问父级的一切
    • HOC mode: Parent Component -> HOC -> Children Component
    • render props mode: Parent Component -> render props -> children Component || Parent Component -> Child Component
    • Render props 存在问题
      1. this.props.children 不该作为函数调用,可以作为属性返回
      2. 渲染颗粒度变大,表格需要性能优化场景不合适
      3. renderProps 不是 React 组件,无法单独使用 redux 等数据管理工具
  • 围绕那么多对于最普通的 props 传参而言可能是一个比较好的方式,renderProps 的控制放权思想也是为了解决组件 dom 结构定制化的问题

    render() {
        return this.props.children
    }
    
    render() {
        return (
        	<div>
            	<Header />
                <Sidebar>
                	<Toolar>
                    	<ul>
                        	<li></li>
                            <li></li>
                        </ul>
                    </Toolar>
                </Sidebar>
            </div>
        )
    }

summary

  • 某些场景下高阶组件也是不错的选择,也不会拒绝使用使用
  • 在不为组件做注入的情况,HOC 的生命周期实现权限,埋点,在层级少是使用依赖注入很方便
  • 在最佳实践的衡量下,不用把最完美的实践全部在代码中重构,没必要局限一种风格或者崇尚多种风格写代码