react 中render-props 模式和高阶组件

1,115 阅读2分钟

@TOC

react 中render-props 模式和高阶组件

组件中功能相似会出现组件复用,那么在 react 怎样实现组件的复用?

  • 组件状态逻辑:1. state 2. 操作state的方法
  • 两种实现方案:1. render props 模式 2. 高阶组件(HOC)

render props 模式

  • 将要服用的 state 和操作 state 的方法封装到一个组件中

  • 对组件外暴露 state 和操作state的方法(子组件向父组件传递数据)

    render() {
        return (
            <div>
                // 对外暴露了,组件状态和操作组件状态的方法
                { this.props.render(this.state.count, this.handleCount) }
            </div>
        )
    }
    
  • 调用父组件传递进来的函数,把 state 和操作 state 的方法作为函数参数传递进去

    <div>
        <Counter 
            render={(count, handleCount) => {
                return <button onClick={handleCount}> 我被点击了{count}次</button>
            }}
        />
    </div>
    

children 代替 render 属性

  • 注意:并不是该模式叫 render props 就必须使用名为 render 的 prop,实际上可以使用任意名称的 prop

  • 把 prop 是一个函数并且告诉组件要渲染什么内容的技术叫做:render props 模式

  • 推荐:使用 children 代替 render 属性

    <Counter>
        {({count, handleCount}) => <button onClick={handleCount}>我被点击了{count}次</button> }
    </Counter>
    // 组件内部:
    this.props.children(this.state.count, this.state.handleCount)
    
    // Context 中的用法:
    <Consumer>
        {data => <span>data参数表示接收到的数据 -- {data}</span>}
    </Consumer>
    

高阶组件

  • 高阶组件(HOC)是一个函数,接受要包装的组件,返回增强后的组件

  • 高阶组件内部创建一个类组件,在这个类组件中提供复用的状态逻辑代码,通过 prop 将复用的状态传递给被包装组件 WrappedComponent

    const EnhancedComponent = withCounter(WrappedComponent)
    
    // 高阶组件内部创建的类组件:
    class Counter extends React.Component {
        render() {
            return <WrappedComponent count={this.state.count}, handleCount={this.handleCount} />
        }
    }
    

使用步骤

  1. 创建一个函数,名称约定以 with 开头

  2. 指定函数参数,参数应该以大写字母开头(作为要渲染的组件)

  3. 在函数内部创建一个类组件,提供服用的状态逻辑代码,并返回此组件

  4. 在该组件中,渲染参数组件,同时将状态通过 prop 传递给参数组件

  5. 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中

    function withCounter(WrappedComponent) {  
        class Counter extends React.Component {}  
        return Counter
    }
    
    // 在render方法中:
    return <WrappedComponent count={this.state.count}, handleCount={this.handleCount} />
    

传递 props

  • 问题:props 丢失

  • 原因:高阶组件没有往下传递 props

  • 解决方式:渲染 WrappedComponent 时,将 state 和 this.props 一起传递给组件

  • 传递方式:

    <WrappedComponent {...this.state} {...this.props} />
    

总结

  1. 组件通讯是构建 React 应用必不可少的一环。
  2. props 的灵活性让组件更加强大。
  3. 状态提升是React组件的常用模式。
  4. 组件生命周期有助于理解组件的运行过程。
  5. 钩子函数让开发者可以在特定的时机执行某些功能。
  6. render props模式和高阶组件都可以实现组件状态逻辑复用。
  7. 组件极简模型: (state, props) => UI