React Render Props Mode

Overview

Render PropsThe pattern is a very flexible and reusable pattern. It can encapsulate a specific behavior or function into a component and provide it to other components so that other components have such capabilities. Next, let's take a step by step look at how React components work. implement such a function.

React component data passing

ReactWe can pass some to a component propsand display it inside the component. Similarly, we can pass some components. It also works. Let's see an example.

1. Component common data transfer

We can pass some string data through the component, and rendering the following code inside the component is commonplace, as is the case with the vast majority of our code.

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. Pass components on components

Going a step further, we can pass common HTML 标签and React 组件reusable components on components

// 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'))

In the above example, passing ordinary HTML 标签components does not help us to reuse components. The key point is to pass componentthis parameter. It is passed to Fooa function of the component. This function returns a component Bar 组件that we will Foo 组件call and display componentin the function. Let's write a small DEMO for verification.

3. A pure Render Propsexample

// 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'))

In the above example, Foo 组件an argument is passed renderit is a function which returns a Barcomponent which takes an argument which was passed titlefrom the Foo 组件call and which we will title 属性pass to again Bar 组件. After the above invocation process, we Bar 组件can share the Foo 组件内部的state property `.

4. By childrenpassing

This demo is slightly different from the above by propspassing, and it is childrenpassing a function through the component toFoo 组件

// 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'))

Observation can be found that there is only a slight modification of the writing method, and the data we will pass is placed in the component children. There is actually no difference (both pass a function)

<Foo>
  {(title) => (
    <Bar title={title} />
  )}
</Foo>

Precautions

Please note that when we Foo 组件inherit from React.PureComponent, we need to avoid the following notation. Otherwise our performance optimizations will be in vain.

render() {
    return (
      <div>
        <h2>这是一个示例组件</h2>
        <Foo render={(title) => <Bar title={title} />} />
      </div>
    );
  }

If you are rendercreating a function that render propwill be a new value each time it is rendered, it will be re-rendered each time Bar.

The correct way should be to create a function inside the component to display the component

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'))

Summarize

Learn to understand Render Propsthe principle of rendering mode, using renderand childrentwo different rendering methods.

Please refer to https://reactjs.org/docs/render-props.html for updated detailed official examples

Official example online reference https://codesandbox.io/embed/1075p1yov3

Follow if you like

thanks for reading

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324520604&siteId=291194637