• React中render Props模式


    React组件复用

    React组件复用的方式有两种:
    1.render Props模式
    2.高阶组件HOC
    上面说的这两种方式并不是新的APi。
    而是利用Raect自身的编码特点,演化而来的固定编码写法。
    

    什么是render Props模式

    1.把prop是一个函数并且要告诉组件要渲染什么内容的技术,叫做render Props模式。
    2.注意的是:并不是该模式叫做render Props就必须使用名为render的props,
    实际上可以使用任意的props。
    对上面者一句话的详细说明:
    子组件向父组件抛出数据的时候使用的是:
    this.props.render(数据)中render可以是其他名,如果GiveFather.
    

    render Props的简单使用

    现在我们有一个有的需求。
    光标放在屏幕上,时时获取当前坐标的位置。
    请封装为一个组件。
    

    MoveCom.js 时时获取当前坐标的位置

    import React from 'react';
    class MoveCom extends React.Component{
      // 提供位置数据
      state = {
        x: 0,
        y:0,
      }
      // 获取鼠标的当前坐标
      moveHandler = e => { 
        this.setState({
            x: e.clientX,
            y:e.clientY
        })
      }
      // 监听鼠标的行为
      componentDidMount() { 
        // DOM已经渲染完成了;可以进行DOM操作
        window.addEventListener('mousemove',this.moveHandler)
      }
      render() { 
        // 将组件中的数据暴露出去this.props.render(数据)
        return this.props.render(this.state)
      }
    }
    export default MoveCom
    

    父组件展示位置

    import React from 'react';
    import ReactDOM from 'react-dom'; 
    import ClassCom from "./components/ClassCom"
    import MoveCom from './components/MoveCom'
    class Father extends React.Component{
      render() { 
        return (
          <div>
            <h2> render Props的简单使用</h2>
            { /* 接受子组件向上抛出来的数据*/}
            <MoveCom render={sonGiveData => {
              return (
                <p>当前鼠标的坐标横坐标: {sonGiveData.x }  纵坐标: {sonGiveData.y }</p>
              )
            }}></MoveCom>
          </div>
        )
      }
    }
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    

    总结

    1. 如何将子组件中的数据抛出去
    render() { 
        return this.props.render(数据) 
    }
    
    父组件接受数据
    <MoveCom render={sonGiveData => {
      return (
        <!-- 渲染的html以及数据 -->
        <p>当前鼠标的坐标横坐标: {sonGiveData } </p>
      )
    }}></MoveCom>
    
    我们发现上面这个组件只实现了状态。
    并没有实现UI结构的渲染。
    UI结构的渲染是交给render函数来决定返回的内容。
    
    小技巧:在React中 left,right,top,bottom是不需要加上px的。
    <p style={{ position:'absolute', left:100, top:200 }}> 不需要加上px的 </p>
    
    this.props.render(数据) 可以将数据传递出去
    再次说明:上面这个render这个不一定非要叫做render。
    只是这样写render了,你页可以叫做Aa,接受的时候使用也用Aa接收。
    
    其实推荐children去代替render。因为这样更加语义化一些的。
    在实际写的过程中也是用children。
    下面我们来将代码更改一下,children去代替render。
    

    children去代替render语法上的变化

    1.使用render子组件向上抛出数据:
    this.props.render(数据) 
    
    1.使用children子组件向上抛出数据:
    this.props.children(数据)
    在向上抛出数据的时候,只是render变为了children。
    
    2.render接受数据:
    <MoveCom render={sonGiveData => {
        return (
            <p>当前鼠标的坐标横坐标: {sonGiveData } </p>
        )
    }}></MoveCom>
    
    2.children接收数据:
    <MoveCom>
      {
        (data) => {
          return (
            <p style={{ position:'absolute', left:data.x, top:data.y }}>
              横坐标: {data.x }  纵坐标: {data.y }
            </p>
          )
        }
      }
    </MoveCom>
    render接收数据的时候,数据是写在组件上
    children接收的时候,将数据写在了里面。
    

    render Props中使用 children去代替render

    子组件
    import React from 'react';
    class MoveCom extends React.Component{
      // 提供位置数据
      state = {
        x: 0,
        y:0,
      }
      // 获取鼠标的当前坐标
      moveHandler = e => { 
        this.setState({
          x: e.clientX,
          y:e.clientY
        })
      }
      // 监听鼠标的行为
      componentDidMount() { 
        // DOM已经渲染完成了;可以进行DOM操作
        window.addEventListener('mousemove',this.moveHandler)
      }
      render() { 
        // 将子组件中的数据暴露出去,render变为了children
        return this.props.children(this.state)
      }
    }
    export default MoveCom
    
    父组件
    import React from 'react';
    import ReactDOM from 'react-dom'; 
    import ClassCom from "./components/ClassCom"
    import MoveCom from './components/MoveCom'
    class Father extends React.Component{
      render() { 
        return (
          <div>
            <h2> render Props的简单使用</h2>
            <MoveCom>
              {
                (data) => {
                  return (
                    <p style={{ position:'absolute', left:data.x, top:data.y }}>
                        横坐标: {data.x }  纵坐标: {data.y }
                    </p>
                  )
                }
              }
            </MoveCom>
          </div>
        )
      }
    }
    
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    

    优化React中render Props模式

    1.推荐给render Props添加一个校验。
    因为render Props接收的是一个函数并且是必须写的。
    // 规则校验
    MoveCom.propTypes = {
      // 如果是使用的children
      children: PropTypes.func.isRequired
      // render: PropTypes.func.isRequired 如果使用使用的render
    }
    
    2.移出事件绑定
     // 组件即将卸载的时候,移出事件监听
    componentWillUnmount() { 
      window.removeEventListener('mousemove',this.moveHandler)
    }
    
    3.这里为什么要移出事件绑定
    而我们在页面中用onClick绑定的事件不需要被移除呢?
    因为onClick是借用react来完成的事件绑定,react会自动帮我们移除。
    这里我们不是借用React来完成的事件绑定,因此我们应该手动移除
    

    子组件优化后的代码

    
    import React from 'react';
    import PropTypes from 'prop-types'
    class MoveCom extends React.Component{
      // 提供位置数据
      state = {
        x: 0,
        y:0,
      }
      // 获取鼠标的当前坐标
      moveHandler = e => { 
        this.setState({
          x: e.clientX,
          y:e.clientY
        })
      }
      // 监听鼠标的行为
      componentDidMount() { 
        // DOM已经渲染完成了;可以进行DOM操作
        window.addEventListener('mousemove',this.moveHandler)
      }
    
      // 组件即将卸载的时候,移出事件监听-优化的地方
      componentWillUnmount() { 
        window.removeEventListener('mousemove',this.moveHandler)
      }
      render() { 
        // 将子组件中的数据暴露出去,render变为了children
        return this.props.children(this.state)
      }
    }
    
    // 规则校验-优化的地方
    MoveCom.propTypes = {
      // 如果是使用的children
      children: PropTypes.func.isRequired
      //  render: PropTypes.func.isRequired 如果使用使用的render
    }
    
    export default MoveCom
    
  • 相关阅读:
    MVCC 过程中会加锁吗?
    OSPF的网络类型
    质量小议13 -- 侥幸
    在雷电模拟器9上安装magisk并安装LSPosed模块以及其Manager管理器(二)之LSPosed的使用
    华为配置旁挂二层组网直接转发示例
    (四)Ansible-其他模块
    Flutter——加载图片的多样玩法
    STTH6010-Y-ASEMI原厂代理意法超快恢复二极管STTH6010-Y
    【Java八股40天-Day4】 集合类2
    论文笔记 Where Would I Go Next? Large Language Models as Human Mobility Predictor
  • 原文地址:https://www.cnblogs.com/IwishIcould/p/16387753.html