React learning notes - Render Props

introduce

  • Render Props refers to the technology of using a prop whose value is a function to share code between React components
  • The component with render prop accepts a function that returns the React element, and calls this function inside the component to implement its own rendering logic
  • It is mainly used to separate logic and reuse code

use

Take the example of mouse & cat in the official document as an example

  1. Create a Mouse component, which is only used to provide reusable state logic codes (States, methods, etc.)
  2. Take the reused state as props The parameters of the render (state) method are exposed outside the component
  3. Use props The return value of render() is used as the content to be rendered
import React from 'react'
class Mouse extends React.Component {
	// Omit operation method
	render(){
		return this.props.render(this.state)
	}
}
//Root component
export default class App extends React.Component {
	render(){
		<Mouse render={ mouse => (
			<div>Current mouse position {mouse.x} {mouse.y}<div>
		)}/>
		//The mouse parameter here is actually the state of the mouse component, because this function is called by passing parameters in the render() of the mouse component
	}
}

Note: this mode is not called render props, so you must use the prop named render. You can use prop with any name. It's just a prop that receives the function that returns the React element.

In fact, the view is determined by the function that returns the React element passed in by the parent component. The render() lifecycle function in the Mouse component just calls the function passed in by prop and returns the view by this function

Use children prop instead of render prop

Composite pattern can also be used to realize code reuse between components, which is similar to the concept of Slot in Vue

import React from 'react'
class Mouse extends React.Component {
	// Omit operation method
	render(){
		return this.props.children(this.state)
	}
}
//Root component
export default class App extends React.Component {
	render(){
		<Mouse>
			{ mouse => (
				<div>Current mouse position {mouse.x} {mouse.y}<div>
			)}
		</Mouse>
	}
}

Since this technology needs to pass a function to the component, it is recommended to check the type of children

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

Render props and react Use purecomponent at the same time

be careful

If you create a function in the render method, using render prop will offset the use of react Advantages of purecomponent

Because a new function will be created every time render() is called for rendering, which will cause prevProps === nextProps to always be false when comparing props

class Mouse extends React.PureComponent {
  // Same code as above
}

class MouseTracker extends React.Component {
  render() {
    return (
      <div>
        <Mouse render={mouse => (
          <Cat mouse={mouse} />
        )}/>
      </div>
    );
  }
}

In this example, since the function transmitted by the render prop of the Mouse component is defined in render(), this will cause a new function to be generated as the render prop of the Mouse component every time the MouseTracker renders, thus offsetting the inheritance from react Effect of purecomponent

Solution

To solve this problem, you can define an instance method and pass it to render prop

class MouseTracker extends React.Component {
  // Define as instance method, ` this Renderthecat ` always
  // When we use it in rendering, it refers to the same function
  renderTheCat(mouse) {
    return <Cat mouse={mouse} />;
  }

  render() {
    return (
      <div>
        <h1>Move the mouse around!</h1>
        <Mouse render={this.renderTheCat} />
      </div>
    );
  }
}

Keywords: Javascript React

Added by MathewByrne on Sat, 19 Feb 2022 23:25:46 +0200