React中的Render Props模式

Render Props是一种react组件之间使用prop数据共享的简单技术,是一种开发时可以使用到的一种技巧,可以实现组件的高可复用性。

假设我们有一个需求,需要获取到鼠标在页面中的一个位置,我们可能会这么写:

interface StateInterface{
    x:number,
    y:number
}

class Mouse extends React.Component<any,StateInterface>{
    constructor(props:any){
        super(props)
        this.state = { x:0, y:0 }
    }
    componentDidMount(){
        document.addEventListener('mousemove', this.fnGetMousePoint)
    }
    fnGetMousePoint=(event:any)=>{
        this.setState({
            x:event.clientX,
            y:event.clientY
        })
        console.log('鼠标的坐标位置:',this.state);
    }
    render(){
        let { x, y } = this.state
        return(
            <div>
                <div style={{ position:'absolute',left:x,top:y,width:50,height:50,backgroundColor:'red' }}></div>
            </div>
        )
    }
}

如果另一个组件也需要使用到这个获取到鼠标位置的功能,这个时候就要再复制一份功能代码,无法实现功能的复用。

如果需要使得Mouse组件中的功能复用的话,可能是需要重构一部分react组件中的代码,从而达到可以组件功能复用的条件:

class Mouse extends React.Component{
    constructor(props:any){
        super(props)
        this.state = { x:0, y:0 }
    }
    componentDidMount(){
        document.addEventListener('mousemove', this.fnGetMousePoint)
    }
    fnGetMousePoint=(event:any)=>{
        this.setState({
            x:event.clientX,
            y:event.clientY
        });
    }
    render(){
        return(
            <div>
                <Cat mouse={this.state}/>
            </div>
        )
    }
}
class Cat extends React.Component<any>{
    render(){
        let {x,y} = this.props.mouse
        return(
            <div>
                <div style={{ position:'absolute',left:x-25,top:y-25,width:50,height:50,backgroundColor:'red' }}></div>
            </div>
        )
    }
}

通过重构Mouse组件中的代码,我们实现了让Cat组件复用了鼠标位置的功能,但是仍然不是真正的实现可复用,因为需要在组件中修改相应的代码,才能达到让指定的组件复用其功能,这种将Cat组件硬编码到Mouse组件中的方式显然并不是我们所需要的。

或许我们是时候使用render props这种方式,看示例:

interface StateInterface{
    x:number,
    y:number
}
class Mouse extends React.Component<any,StateInterface>{
    constructor(props:any){
        super(props)
        this.state = { x:0, y:0 }
    }
    componentDidMount(){
        document.addEventListener('mousemove', this.fnGetMousePoint)
    }
    fnGetMousePoint=(event:any)=>{
        this.setState({
            x:event.clientX,
            y:event.clientY
        })
    }
    render(){
        return(
            <div>
                { this.props.render( this.state ) }
            </div>
        )
    }
}
class Cat extends React.Component<any>{
    render(){
        let {x,y} = this.props.mouse
        return(
            <div>
                <div style={{ position:'absolute',left:x-25,top:y-25,width:50,height:50,backgroundColor:'red' }}></div>
            </div>
        )
    }
}
class MouseTracker extends React.Component{
    render(){
        return(
            <div>
                <Mouse render={ (mouse:any)=>(
                    <Cat mouse={mouse}/>
                )}/>
            </div>
        )
    }
}

我们从Mouse中用一个props拿到一个父组件的render函数,然后将Mouse中的数据以实参的方式传递出去,以父传子的方式将数据传递到Cat组件身上使用,这样就可以实现动态的将数据给Cat组件了,而不是在Mouse组件身上动代码。我们可以利用render props来实现大多数的高阶组件

最后,我们需要注意的是,render prop是因为模式才被称之为render prop,我们不需要局限于render的prop来使用这种模式,我们例子上使用的是render,但是我们也可以使用别的名称来代替这个render,比如使用child prop这种!

<Mouse child={ (mouse:any)=>(
	<Cat mouse={mouse}/>
)}/>

/******************************/
 
// 使用的时候跟prop一一对应即可
{ this.props.child( this.state ) }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值