render-props

React组件复用概述

  处理方式:复用相似的功能(联想函数封装)

  复用:1.state 2.操作state的方法(组件状态逻辑)

  两种方式:1.render props模式 2.高阶组件(HOC)

  注意:这两种方式不是新的API,而是利用React自身特点的编码技巧,演化而成的固定模式(写法)

 

render props模式

思路分析

  思路:将要复用的state和操作state的方法封装到一个组件中

  在使用组件时,添加一个值为函数的prop,通过函数参数来获取(需要组件内部实现)

  使用该函数的返回值作为要渲染的UI内容(需要组件内部实现)

使用步骤

1.创建Mouse组件,在组件中提供复用的逻辑状态代码(1.状态 2.操作状态的方法)

2.将要复用的状态作为props.render(state)方法的参数,暴露到组件外部

3.使用props.render()的返回值作为要渲染的内容

//1. 导入react
import React from 'react';
import ReactDOM from 'react-dom';

/*
  render props 模式
*/

//创建Mouse组件
class Mouse extends React.Component {
  //鼠标位置state
  state = {
    x:0,
    y:0
  }

  //鼠标移动事件的事件处理程序
  handelMouseMove = e => {
    this.setState({
      x: e.clientX,
      y: e.clientY
    })
  }

  //监听鼠标移动事件
  componentDidMount() {
    window.addEventListener('mousemove', this.handelMouseMove)
  }
  render() {
    // return null
    return this.props.render(this.state)
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>render props 模式</h1>
        <Mouse render={(mouse) => {
          return (
          <p>
            鼠标位置:{mouse.x} {mouse.y}
          </p>
          )
        }} />
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

Mouse组件的复用

//1. 导入react
import React from 'react';
import ReactDOM from 'react-dom';

/*
  render props 模式
*/

//导入图片资源
import img from './images/cat.jpg'

//创建Mouse组件
class Mouse extends React.Component {
  //鼠标位置state
  state = {
    x:0,
    y:0
  }

  //鼠标移动事件的事件处理程序
  handelMouseMove = e => {
    this.setState({
      x: e.clientX,
      y: e.clientY
    })
  }

  //监听鼠标移动事件
  componentDidMount() {
    window.addEventListener('mousemove', this.handelMouseMove)
  }
  render() {
    // return null
    return this.props.render(this.state)
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>render props 模式</h1>
        <Mouse render={(mouse) => {
          return (
          <p>
            鼠标位置:{mouse.x} {mouse.y}
          </p>
          )
        }} />

        {/* 猫捉老鼠 */}
        <Mouse render={mouse => {
          return <img src={img} alt="猫" style={{
            position:'absolute',
            top:mouse.y,
            left:mouse.x
          }}></img>
        }} />
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))

 推荐使用children代替render属性

<Mouse>

  { ({x, y}) => <p>鼠标的位置是 {x}, {y}</p> }

</Mouse>

//组件内部

this.props.children(this.state)


//1. 导入react
import React from 'react';
import ReactDOM from 'react-dom';

/*
  render props 模式
*/

//导入图片资源
import img from './images/cat.jpg'

//创建Mouse组件
class Mouse extends React.Component {
  //鼠标位置state
  state = {
    x:0,
    y:0
  }

  //鼠标移动事件的事件处理程序
  handelMouseMove = e => {
    this.setState({
      x: e.clientX,
      y: e.clientY
    })
  }

  //监听鼠标移动事件
  componentDidMount() {
    window.addEventListener('mousemove', this.handelMouseMove)
  }
  render() {
    // return null
    // return this.props.render(this.state)
    return this.props.children(this.state)
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>render props 模式</h1>
        {/* <Mouse render={(mouse) => {
          return (
          <p>
            鼠标位置:{mouse.x} {mouse.y}
          </p>
          )
        }} /> */}



        <Mouse>
          {
            mouse => {
              return (
                <p>
                  鼠标位置:{mouse.x} {mouse.y}
                </p>
                )
            }
          }
        </Mouse>

        <Mouse>
          {
            mouse => {
              return (
                <img src={img} alt="猫" style={{
                  position:'absolute',
                  top:mouse.y,
                  left:mouse.x
                }}></img>
              )
            }
          }
        </Mouse>

        {/* 猫捉老鼠 */}
        {/* <Mouse render={mouse => {
          return <img src={img} alt="猫" style={{
            position:'absolute',
            top:mouse.y,
            left:mouse.x
          }}></img>
        }} /> */}
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
 

 render-props 优化

1.给render props 模式添加props校验

2.应该在组件卸载时解除mousemove事件绑定

 
// import PropTypes from 'prop-types'
//添加props校验
Mouse.proTypes = {
  children:PropTypes.func.isRequired
}



//在组件卸载时移除事件绑定
  componentWillUnmount() {
    window.removeEventListener('mousemove', this.handelMouseMove)
  }
 
posted @ 2021-11-09 16:58  wslfw  阅读(80)  评论(0)    收藏  举报