小编给大家分享一下Render props是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
Render props
Rrender prop 是指一种在 React 组件之间
使用一个值为函数的 prop 共享代码
的简单技术, 和 HOC 类似, 都是组件间的逻辑复用问题
。
更具体地说,Render prop 是一个用于告知组件需要渲染什么内容
的函数。
下面看一下简单的例子:
以下组件跟踪 Web 应用程序中的鼠标位置:
class Mouse extends React.Component { state = { x: 0, y: 0 }; handleMouseMove = (event) => { this.setState({ x: event.clientX, y: event.clientY }); } render() { return ( <p style={{ height: '100%' }} onMouseMove={this.handleMouseMove}> <p>The current mouse position is ({this.state.x}, {this.state.y})</p> </p> ); }}class MouseTracker extends React.Component { render() { return ( <> <h2>移动鼠标!</h2> <Mouse /> </> ); }}
当光标在屏幕上移动时,组件显示其(x,y)坐标。
现在的问题是:
我们如何在另一个组件中复用这个行为?
换个说法,若另一个组件需要知道鼠标位置,我们能否封装这一行为,以便轻松地与其他组件共享它 ??
假设产品想要这样一个功能: 在屏幕上呈现一张在屏幕上追逐鼠标的猫的图片。
我们或许会使用 <Cat mouse={{ x, y }} prop 来告诉组件鼠标的坐标以让它知道图片应该在屏幕哪个位置。
class Cat extends React.Component { render() { const mouse = this.props.mouse; return ( <img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} /> ); }}
这个需求如此简单,你可能就直接修改Mouse组件了:
class Mouse extends React.Component { state = { x: 0, y: 0 }; handleMouseMove = (event) => { this.setState({ x: event.clientX, y: event.clientY }); } render() { return ( <p style={{ height: '100%' }} onMouseMove={this.handleMouseMove}> <Cat mouse={this.state} /> </p> ); }}
巴适~ 简单粗暴, 一分钟完成任务。
可是,如果下次产品再要想加条狗呢
?
以上的例子,虽然可以完成了猫追鼠标的需求,还没有达到以可复用的方式
真正封装行为的目标。
当我们想要鼠标位置用于不同的用例时,我们必须创建一个新的组件,专门为该用例呈现一些东西.
这也是 render prop 的来历:
我们可以提供一个带有函数 prop 的 <Mouse>
组件,它能够动态决定
什么需要渲染的,而不是将 <Cat> 硬编码
到 <Mouse> 组件里.
修改一下上面的代码:
class Cat extends React.Component { render() { const mouse = this.props.mouse; return ( <img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} /> ); }}class Mouse extends React.Component { state = { x: 0, y: 0 }; handleMouseMove = (event) => { this.setState({ x: event.clientX, y: event.clientY }); } render() { return ( <p style={{ height: '100%' }} onMouseMove={this.handleMouseMove}> {this.props.render(this.state)} </p> ); }}class MouseTracker extends React.Component { render() { return ( <p> <h2>移动鼠标!</h2> <Mouse render={mouse => ( <Cat mouse={mouse} /> )}/> </p> ); }}
提供了一个render 方法,让动态决定什么需要渲染。
事实上,render prop 是因为模式才被称为 render prop ,不一定要用名为 render 的 prop 来使用这种模式。
任何被用于告知组件需要渲染什么内容的函数 prop, 在技术上都可以被称为 "render prop".
另外,关于 render prop 一个有趣的事情是你可以使用带有 render prop 的常规组件来实现大多数高阶组件 (HOC)。
例如,如果你更喜欢使用 withMouse HOC 而不是 <Mouse> 组件,你可以使用带有 render prop 的常规 <Mouse> 轻松创建一个:
function withMouse(Component) { return class extends React.Component { render() { return ( <Mouse render={mouse => ( <Component {...this.props} mouse={mouse} /> )}/> ); } }}
也是非常的简洁清晰。
有一点需要注意的是, 如果你在定义的render函数里创建函数, 使用 render prop 会抵消
使用 React.PureComponent 带来的优势。
因为浅比较 props 的时候总会得到 false,并且在这种情况下每一个 render 对于 render prop 将会生成一个新的值
。
class Mouse extends React.PureComponent { // 与上面相同的代码......}class MouseTracker extends React.Component { render() { return ( <> <Mouse render={mouse => ( // 这是不好的! 每个渲染的 `render` prop的值将会是不同的。 <Cat mouse={mouse} /> )}/> </> ); }}
在这样例子中,每次 <MouseTracker> 渲染,它会生成一个新的函数作为 <Mouse render> 的 prop,因而在同时也抵消了继承自 React.PureComponent 的 <Mouse> 组件的效果.
为了绕过这一问题
,有时你可以定义一个 prop 作为实例方法
,类似这样:
class MouseTracker extends React.Component { renderTheCat(mouse) { return <Cat mouse={mouse} />; } render() { return ( <p> <h2>Move the mouse around!</h2> <Mouse render={this.renderTheCat} /> </p> ); }}
以上是“Render props是什么”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!