React 进阶 Render Props

作者: zidea | 来源:发表于2019-05-16 19:56 被阅读9次
    react

    通过实现一个切换组件我们来深化一下对 React 理解,我们的研究是从一个示例开始,创建一个切换的按钮来切换部分内容显示和隐藏。
    创建一个 button 作为操作切换状态的触发器。

    <button>显示/隐藏</button>
    

    定义状态 state,页面有两个状态分别是

    • on:true 显示内容
    • on:false 隐藏内容
      通过更新状态 state 来更新界面,状态更新了会更新 dom 。
        state = {
            on:false,
        }
    

    定义 toggle 方法主要用于负责更新 state 中 on 的值来控制页面状态,隐藏/显示界面

        toggle = () => {
            this.setState({
                on:!this.state.on
            })
        }
    

    简单实现

        {
              this.state.on && (
                <h1>Zidea</h1>        
              )
          }
    
    import React, { Component } from 'react'
    
    export default class Toggle extends Component {
        state = {
            on:false,
        }
    
        toggle = () => {
            this.setState({
                on:!this.state.on
            })
        }
      render() {
        return (
          <div className={toggleStyle}>
          {
              this.state.on && (
                <h1>Zidea</h1>        
              )
          }
            <button onClick={this.toggle}>显示/隐藏</button>
          </div>
        )
      }
    }
    
    const toggleStyle = {
        background:"blue"
    }
    
    

    我们的控制要显示或隐藏内容是不是一层不变的,为更灵活的考虑,可能控制内容根据不同情况(场景)会有所不同,我们将这部分内容作为 children 参数传入来提供组件复用性。

      render() {
        return (
          <div className={toggleStyle}>
          {
              this.state.on && (
                this.props.children       
              )
          }
            <button onClick={this.toggle}>显示/隐藏</button>
          </div>
        )
      }
    
          <div>
            <Toggle>
                <h1>angular basic tut</h1>
            </Toggle>
          </div>
    

    Render props

    从字面上不难理解为 render 的属性传入组件,来控制渲染。

      render() {
        return (
          <div>
            <ToggleRenderProps render={()=>(
                <div>
                <h1>tut list</h1>
                <button>隐藏/显示</button>
                </div>
            )}/>
                
          </div>
        )
      }
    

    然后我们通过 props 方法到作为 props 传入的参数来使用,可以调用 render 函数将界面渲染出来。

      render() {
          const { render} = this.props;
        return (
          <div>
            {render()}
          </div>
        )
      }
    

    既然 render 函数,是不是可以将参数参入函数来使用呢?当然没有问题,我们可以尝试在组件内部来控制组件显示。

            <ToggleRenderProps render={(str)=>(
                <div>
                <h1>{str}</h1>
                <button>隐藏/显示</button>
                </div>
            )}/>
    

    这样就顺利将 hello zidea 显示到我们的界面上了。

      render() {
          const { render} = this.props;
        return (
          <div>
            {render('hello zidea')}
          </div>
        )
      }
    

    既然可以可以传参数,那么也可以传入一个对象进入界面。

          <div>
            {render({
                on:this.state.on,
                toggle:this.toggle
            })}
          </div>
    

    这样我们 render 方法就可以接收到组件内部 state 和 toggle 方法来控制行为,这样就将功能和界面成功进行分离来实现更灵活的效果。

      render() {
        return (
          <div>
            <ToggleRenderProps render={({on, toggle})=>(
                <div>
                {
                    on && <h1>Hey zidea</h1>
                }
                
                <button onClick={toggle}>隐藏/显示</button>
                </div>
            )}/>
                
          </div>
        )
      }
    

    其实这里 render 我们给其任意名称,render 只是一个名称而已,既然这样我们可以可以用 children ,children 使我们的固有函数

      render() {
          const { children } = this.props;
            return children({
                on:this.state.on,
                toggle:this.toggle
            })
          }
    
      render() {
        return (
          <div>
            <ToggleRenderRPC>
               { ({on,toggle}) => (
                    <div>
                        {on && <h1>Zidea React</h1>}
                        <button onClick={toggle}>显示/隐藏</button>
                    </div>
                )}
            </ToggleRenderRPC>
          </div>
        )
      }
    
    import React, { Component,Fragment } from 'react'
    

    在 react 新特性中提供 Fragment 。

      render() {
        return (
          <div>
            <ToggleRenderRPC>
               { ({on,toggle}) => (
                    <Fragment>
                        {on && <h1>Zidea React</h1>}
                        <button onClick={toggle}>显示/隐藏</button>
                    </Fragment>
                )}
            </ToggleRenderRPC>
          </div>
        )
      }
    
    avascript

    相关文章

      网友评论

        本文标题:React 进阶 Render Props

        本文链接:https://www.haomeiwen.com/subject/riqiaqtx.html