Render Props是一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术。
例如:
<MyComponent render={data => (
<p>hello {data}</p>
)} />
组件是React中最基础的代码复用单元,render props是一种灵活并且复用性非常高的模式。它可以把特定行为或功能封装成一个组件,提供给其他组件让其拥有这样的能力。
1、render props例子
我们先来看个简单的render props的demo,这个demo是封装了个鼠标组件,用于获取鼠标的x,y的位置信息:
import React,{ Component } from 'react';
const Info = ({mouse})=> (<p>{mouse.x +","+ mouse.y}</p>);
class Mouse extends Component {
constructor(props){
super(props);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.state = {x:0,y:0}
}
handleMouseMove(event){
this.setState({
x:event.clientX,
y:event.clientY
});
}
render(){
return(
<div style={{ height: '50%' }} onMouseMove={this.handleMouseMove}>
鼠标位置x,y:{this.props.render(this.state)}
</div>
);
}
}
export default class RenderMouse extends Component {
render() {
return (
<div>
<h2>移动鼠标获取位置</h2>
<Mouse render={mouse =>
<Info mouse={mouse} />
} />
</div>
);
}
}
我们想要获得鼠标的位置信息,只要渲染一个带有render prop的<Mouse/>组件,组件中通过mouse参数将数据传递到Info里面,我们在<Mouse/>里调用render将数据传递到Info里面,实现位置信息的显示。
2、children prop例子
render prop 是因为模式才被称为 render prop,所以不一定要用名为render的prop来使用这种模式。
任何被用于告知组件需要渲染什么内容的函数 prop 在技术上都可以被称为 "render prop"。
//RenderMouse.js
<Mouse children={mouse =>
<Cat mouse={mouse} />
} />
//Mouse.js
{this.props.children(this.state)}
其实和上面render props的例子一样,就是render变成了children。当然也可以换成其他的,譬如:myRender等。
3、render props与React.PureComponent一起使用时注意的问题
先来说说React.Component 与 React.PureComponent的区别:
- 继承PureComponent时,不能再重写shouldComponentUpdate,否则会引发警告
- 继承PureComponent时,进行的是浅比较,也就是说,如果是引用类型的数据,只会比较是不是同一个地址,而不会比较具体这个地址存的数据是否完全一致
引用官方文档的话:
如果你在 render 方法里创建函数,那么使用 render prop 会抵消使用
React.PureComponent
带来的优势。因为浅比较 props 的时候总会得到 false,并且在这种情况下每一个render
对于 render prop 将会生成一个新的值。
所以,当使用render prop时每次都会是一个新的值,对于继承PureComponent来说,如果是同一个地址就不会重新渲染,但是使用了render props后值都变成一个新的值,这样就会重新渲染。
从而将使用PureComponent带来的性能优化付之东流了。
解决方案:
在组件内部创建一个函数用于显示组件:
export default class RenderMouse extends Component {
//显示组件的函数
renderMouse(mouse){
return <Cat mouse={mouse} />
}
render() {
return (
<div>
<h2>移动鼠标获取位置</h2>
//此处调用这个函数
<Mouse render={this.renderMouse} />
</div>
);
}
}
如例子所示,可以和之前的代码做比较。
写在最后:
- 如果文章中有错误或是表达不准确的地方,欢迎大家评论中指正,以便我完善。
- 文章我也会根据所学到新的知识不断更新。
网友评论