亲宝软件园·资讯

展开

React Render Props共享代码技术

绿胡子大叔 人气:0

介绍

使用

以官方文档的Mouse & Cat示例为例

import React from 'react'
class Mouse extends React.Component {
	// 省略操作方法
	render(){
		return this.props.render(this.state)
	}
}
//根组件
export default class App extends React.Component {
	render(){
		<Mouse render={ mouse => (
			<div>当前鼠标位置 {mouse.x} {mouse.y}<div>
		)}/>
		//此处的mouse参数实际上为Mouse组件的state,因为这个函数是在Mouse组件的render()中传参调用的
	}
}

注意:并不是该模式名叫render props就一定要用名为renderprop。你可以使用任意名称的prop,它只是一个接收返回React元素的函数的prop

实际上,视图是由父组件传入的返回React元素的函数决定的,Mouse组件中的render()生命周期函数只是调用这个由prop传入的函数,并由该函数返回视图

使用children prop代替render prop

也可以使用组合模式来实现组件间的代码重用,该方法类似于Vue中Slot的概念

import React from 'react'
class Mouse extends React.Component {
	// 省略操作方法
	render(){
		return this.props.children(this.state)
	}
}
//根组件
export default class App extends React.Component {
	render(){
		<Mouse>
			{ mouse => (
				<div>当前鼠标位置 {mouse.x} {mouse.y}<div>
			)}
		</Mouse>
	}
}

由于这一技术需要向组件传递一个函数,所以推荐对children进行类型检查

import PropTypes from 'prop-types'
Mouse.propTypes = {
	children: PropTypes.func.isRequired
}

Render props 与 React.PureComponent 同时使用

注意

如果在render方法中创建函数,那么使用render prop会抵消使用React.PureComponent带来的优势

因为每次调用render()进行渲染时都会创建一个新的函数,这将导致浅比较props的时候prevProps === nextProps始终为false

class Mouse extends React.PureComponent {
  // 与上面相同的代码......
}
class MouseTracker extends React.Component {
  render() {
    return (
      <div>
        <Mouse render={mouse => (
          <Cat mouse={mouse} />
        )}/>
      </div>
    );
  }
}

在这个示例中,由于Mouse组件的render prop传输的函数是在render()中定义的,这将导致每次MouseTracker渲染时生成一个新的函数作为Mouse组件的render prop,因而抵消了继承自React.PureComponent的效果

解决方案

为了解决这一问题,可以定义一个实例方法传给render prop

class MouseTracker extends React.Component {
  // 定义为实例方法,`this.renderTheCat`始终
  // 当我们在渲染中使用它时,它指的是相同的函数
  renderTheCat(mouse) {
    return <Cat mouse={mouse} />;
  }
  render() {
    return (
      <div>
        <h1>Move the mouse around!</h1>
        <Mouse render={this.renderTheCat} />
      </div>
    );
  }
}

加载全部内容

相关教程
猜你喜欢
用户评论