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 

发表评论

相关文章