官方介绍:
术语 “render prop” 是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术
具有 render prop 的组件接受一个函数,该函数返回一个 React 元素并调用它而不是实现自己的渲染逻辑。
看了官方的介绍和例子,还是不容易理解, 照着案例写了一遍,大概明白了其中的关系。
render props 模式的目的是实现组件复用(状态 state 和操作state的方法)。
实现方式其实就是利用函数回调传参的方式。
在 Mouse 组件中封装了公共状态(鼠标的坐标),在 MouseTracker 组件中使用的时候,传入一个函数 props, 然后 Mouse 组件在自己内部调用传过来的函数,并将状态作为参数传递给函数,MouseTracker 组件中,就可以拿到需要的状态,然后该函数可以 return 一个任意想要渲染的 UI 结构,而这个返回值又会在 Mouse 组件中调用函数的位置作为结果来渲染。
具体看下面的例子
class Mouse extends React.Component {
state = {
x: 0,
y: 0,
};
componentDidMount() {
window.addEventListener('mousemove', this.handleMouseMove);
}
componentWillUnmount() {
window.removeEventListener('mousemove', this.handleMouseMove);
}
handleMouseMove = (e) => {
this.setState({
x: e.clientX,
y: e.clientY,
});
};
render() {
// this.props.render 是一个函数
// 调用函数时将状态传递出去
// 调用函数之后的结果作为 render 要渲染的UI
return this.props.render(this.state);
}
}
在 MouseTracker 中复用鼠标位置状态。
class MouseTracker extends React.Component {
render() {
return (
<div>
{/* point: 形参接收传过来的状态(鼠标位置) */}
{/* 函数要返回想要渲染的UI,会在调用的地方渲染 */}
<Mouse
render={(point) => {
return (
<p>
鼠标当前位置:({point.x}, {point.y})
</p>
);
}}
/>
</div>
);
}
}
如果有其他组件需要使用鼠标位置,类似上面的使用方法即可实现复用。
重要的是要记住,render prop 是因为模式才被称为 render prop ,你不一定要用名为 render
的 prop 来使用这种模式
所以,可以使用 children 代替 render。
-
- 只需要将 Mouse 组件中 this.props.render(this.state) 替换为 this.props.children(this.state)
-
- 使用的时候,不需要添加 render 属性,而是直接将函数写在组件中间。
class Mouse extends React.Component {
// ...省略的相同部分,具体参考上面示例
render() {
return this.props.children(this.state);
}
}
class MouseTracker extends React.Component {
render() {
return (
<div>
<Mouse>
{/* 要注意使用 children 时,是写在组件中间的 */}
{(point) => {
return (
<p>
children-props 鼠标当前位置:({point.x}, {point.y})
</p>
);
}}
</Mouse>
</div>
);
}
}
完