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')
)

《React中render Props模式》

总结

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
    原文作者:南风晚来晚相识
    原文地址: https://www.cnblogs.com/IwishIcould/p/16387753.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞