React中render Props模式
Web前端之巅 2022-08-19 15:48:30 2022-08-19 47 0
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