React Render Props 模式
2018-04-10 23:42
375 查看
概述
Render Props模式是一种非常灵活复用性非常高的模式,它可以把特定行为或功能封装成一个组件,提供给其他组件使用让其他组件拥有这样的能力,接下来我们一步一步来看React组件中如何实现这样的功能。
React 组件数据传递
React中我们可以给一个组件传递一些
props并且在组件内部展示,同样的我们也可以传递一些组件同样也是行得通的,一起看一个例子
1. 组件普通数据传递
我们可以通过组件传递一些字符串数据,并且在组件内部渲染下面的代码很平常,我们绝大多数代码都是这样。
const Foo = ({ title }) => ( <div> <p>{title}</p> </div> ); class App extends React.Component { render() { return ( <div> <h2>这是一个示例组件</h2> <Foo title="大家好,我是土豆" /> </div> ); } } ReactDOM.render(<App />, document.getElementById('app'))
2. 组件上传递组件
更进一步,我们可以在组件上传递普通的HTML 标签和
React 组件达到复用的目的
// https://codepen.io/tudou/full/OvdrPW const Bar = () => (<p>我是Bar组件 :)</p>); const Foo = ({ title, component }) => ( <div> <p>{title}</p> {component()} </div> ); class App extends React.Component { render() { return ( <div> <h2>这是一个示例组件</h2> <Foo title={<p>大家好,我是土豆</p>} component={() => <Bar /> } /> </div> ); } } ReactDOM.render(<App />, document.getElementById('app'))
在上面的例子中传递普通的
HTML 标签对我们复用组件没有任何帮助,重点可以看传递
component这个参数,它传递给
Foo组件一个函数这个函数返回的是一个
Bar 组件,我们会在
Foo 组件中调用并且显示
component函数中的组件。我们再来写一个小的DEMO进行验证。
3. 一个纯粹的Render Props
例子
// https://codepen.io/tudou/full/dmawvY const Bar = ({ title }) => (<p>{title}</p>); class Foo extends React.Component { constructor(props) { super(props); this.state = { title: '我是一个state的属性' }; } render() { const { render } = this.props; const { title } = this.state; return ( <div> {render(title)} </div> ) } } class App extends React.Component { render() { return ( <div> <h2>这是一个示例组件</h2> <Foo render={(title) => <Bar title={title} />} /> </div> ); } } ReactDOM.render(<App />, document.getElementById('app'))
在上面的例子中,给
Foo 组件传递了一个
render参数它是一个函数这个函数返回一个
Bar组件,这个函数接受一个参数
title他来自于
Foo 组件调用时传递并且我们又将
title 属性传递给了
Bar 组件。经过上述的调用过程我们的
Bar 组件就可以共享到
Foo 组件内部的state 属性`。
4. 通过children
传递
这个demo略微不同于上面通过props传递,而它是通过组件的
children传递一个函数给
Foo 组件
// https://codepen.io/tudou/full/WzPPeL const Bar = ({ title }) => (<p>{title}</p>); class Foo extends React.Component { constructor(props) { super(props); this.state = { title: '我是一个state的属性' }; } render() { const { children } = this.props; const { title } = this.state; return ( <div> {children(title)} </div> ) } } class App extends React.Component { render() { return ( <div> <h2>这是一个示例组件</h2> <Foo> {(title) => ( <Bar title={title} /> )} </Foo> </div> ); } } ReactDOM.render(<App />, document.getElementById('app'))
观察可发现只是写法略微有些变法,我们将要传递的数据放到的组件的
children。实际上并无不同之处(都是传递一个函数)
<Foo> {(title) => ( <Bar title={title} /> )} </Foo>
注意事项
请注意当我们的Foo 组件继承于
React.PureComponent的时候,我们需要避免下面这样的写法。不然我们的性能优化将付之东流。
render() { return ( <div> <h2>这是一个示例组件</h2> <Foo render={(title) => <Bar title={title} />} /> </div> ); }
如果你在
render创建一个函数,在每次渲染的时候
render prop将会是一个新的值,那么每次将会重新渲染
Bar。
正确的做法应该是在组件内部创建一个函数用于显示组件
const Bar = ({ title }) => (<p>{title}</p>); class Foo extends React.Component { constructor(props) { super(props); this.state = { title: '我是一个state的属性' }; } render() { const { render } = this.props; const { title } = this.state; return ( <div> {render(title)} </div> ) } } class App extends React.Component { // 单独创建一个渲染函数 renderFoo(title) { return <Bar title={title} />; } render() { return ( <div> <h2>这是一个示例组件</h2> <Foo render={this.renderFoo} /> </div> ); } } ReactDOM.render(<App />, document.getElementById('app'))
总结
学习了解Render Props渲染模式原理,使用了
render和
children两种不同的渲染方法。
更新详细的官方例子请参考https://reactjs.org/docs/render-props.html
官方例子在线参考 https://codesandbox.io/embed/1075p1yov3
如果喜欢请关注
谢谢阅读
相关文章推荐
- [Recompose] Refactor React Render Props to Streaming Props with RxJS and Recompose
- [React] Implement a Higher Order Component with Render Props
- React 语法一:React.createClass()、ReactDOM.render()、props、state和componentDidMount()
- [React] Use Prop Collections with Render Props
- 第05节、React组件:props和render成员
- 混合开发的大趋势之一React Native Props (属性)
- React 源码分析-调用ReactDOM.render后发生了什么
- react更新props后this.props === nextProps
- 10个React小模式
- 利用Immutable解决React-Native那些因为对象被篡改导致的多次render问题
- React系列三——props属性
- [React] Validate Custom React Component Props with PropTypes
- React学习笔记-模板、ReactDOM.render()、JSX语法
- ReactJS学习系列课程(props 组件属性)
- 【转载】React 数据流与状态控制-props与sate的区别
- react-bits:Render Callback
- 通过componentWillReceiveProps()实现React左右父子页面的联动效果
- 混合开发的大趋势之一React Native Props (属性)
- 【react】利用prop-types第三方库对组件的props中的变量进行类型检测
- reactJS -- 5 Props 属性