09.Render-props

Posted foreverluckystar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了09.Render-props相关的知识,希望对你有一定的参考价值。

React组件复用

思考:如果两个组件中的部分功能相似或相同,该如何处理?
处理方式:复用相似的功能(函数封装)
复用什么?1.state   2.操作state的方法(组件状态逻辑)
两种方式:1.render props模式  2.高阶组件(HOC)
注意:这两种方式不是新的API,而是利用React自身特点的编程技巧,演化而成的固定模式(写法)

render props模式

思路分析

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

问题1:如何拿到该组件中复用的state?
在使用组件时,添加一个值为 函数的prop.通过函数参数 来获取(需要组件内部实现)
问题2:如何渲染任意的UI?
使用该函数的返回值作为要渲染的UI内容(需要组件内部实现)

<Mouse render={(mouse)=>(
    <p>鼠标当前位置{mouse.x},{mouse.y}</p>
)}/>

使用步骤

1.创建Mouse组件,在组件中提供复用的状态逻辑代码(1,状态  2,操作状态的方法)
2.将要复用的状态 作为props.render(state)方法的参数,暴露到组件外部
3.使用props.render() 的返回值作为要渲染的内容
//创建Mouse组件
class Mouse extends React.Component{
    //鼠标位置 state
    state={
        x:0,
        y:0
    }
    //鼠标移动事件的事件处理程序
    handleMouseMove = e => {
        this.setState({
            x:e.clientX,
            y:e.clientY
        })

    }
    //监听鼠标移动事件
    componentDidMount(){
        window.addEventListener('mousemove',this.handleMouseMove)
    }
    render(){
        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组件复用

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={{width:'100px',height:'100px',position:'absolute',top:mouse.y-50,left:mouse.x-50}}/>
                                        
                }} />
            </div>
        )
    }
}

children代替render属性

注意:并不是该模式叫做 render props 就必须使用名为render 的prop,实际上可以使用任意名称prop
把prop 是一个函数并且告诉组件要渲染什么内容的技术叫做 :render props模式
建议:使用children 代替 render
import img from './images/33.jpeg'

//创建Mouse组件
class Mouse extends React.Component{
    //鼠标位置 state
    state={
        x:0,
        y:0
    }
    //鼠标移动事件的事件处理程序
    handleMouseMove = e => {
        this.setState({
            x:e.clientX,
            y:e.clientY
        })

    }
    //监听鼠标移动事件
    componentDidMount(){
        window.addEventListener('mousemove',this.handleMouseMove)
    }
    render(){
        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={{width:'100px',height:'100px',position:'absolute',top:mouse.y-50,left:mouse.x-50}}/>
                                        
                }} />
            </div>
        )
    }
}

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

 return this.props.children(this.state)
class App extends React.Component{
    render(){
        return(
            <div>
                <h1>render props 模式</h1>
                <Mouse>
                    {mouse =>{
                    return <p>鼠标位置:{mouse.x} {mouse.y}</p>
                    }}
                </Mouse> 
                
                {/* 猫抓老鼠 */}
                <Mouse>
                {mouse =>{
                    return  <img src={img} alt="猫" style={{width:'100px',height:'100px',position:'absolute',top:mouse.y-50,left:mouse.x-50}}/>
                                        
                }}
                </Mouse> 
            </div>
        )
    }
}

优化

1.推荐 : 给render props 模式添加 props校验
//添加props校验
Mouse.propTypes = {
    children:PropTypes.func.isRequired
}

2.应该在组件卸载时解除 mousemove 事件绑定
 //推荐在组件卸载时移除事件绑定
    componentWillUnmount(){
        window.removeEventListener('mousemove',this.handleMouseMove)
    }

以上是关于09.Render-props的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数