“This is the 13th day of my participation in the November Gwen Challenge. See details: The Last Gwen Challenge 2021”.

Render props is a technique for sharing code between React components using a prop with a value of function.

Simply put, if you pass a prop to a component, the props is a function that tells the component what to render.

For a use scenario for render props, let’s look at some code:

/ / A component
class A extends Component {
    state = { count: 0 };
    add = () = > {
        this.setState({ count: this.state.count + 1 });
    };
    render() {
        return (
            <div className="a">
                <h2>A component</h2>
                <button onClick={this.add}>add</button>
                <B count={this.state.count} />
            </div>); }}/ / B component
class B extends Component {
    render() {
        return <h3 className="b">B component, {this.props. Count}</h3>; }}/ / Father components
export default class Father extends Component {
    render() {
        return (
            <div className="father">
                <h2>Father components</h2>
                <A />
            </div>); }}Copy the code

The outermost layer is A Father component, which has an A component as A child. In the STATE of the A component, count is defined to count and is incremented by clicking the button. At the same time, in component A, A component B is nested as A child component, and the count value in component A is passed to component B. The COMPONENT B receives the count through props and displays it on the page. The relationship and operation effect of each component are shown as follows:

The code above does the trick: control count in component A and display the count value in component B. However, this nesting of A and B components is fixed.

Suppose we don’t want B to be A child of A, we want another C component to display count as A child of A; Or, you might want to have another A, but the child of that A is not B but C. At this point, we need to change the code in component A to replace component B with component C, which is obviously not efficient or elegant. The state in component A and the code logic controlling the count value in state are the same, but we did not reuse them.

Render props solve this problem by encapsulating fixed logic to dynamically determine what needs to be rendered. The state in the A component and the code logic that controls the count count in the state remain the same. All that changes is who is A child of A, which could be B or C. We can then leave an empty space where we need to render child components, and we can choose either render B or render C in the future. In this way, unchanging logic is reused and the content to be rendered can be dynamically selected.

How to achieve it? Take a look at the following code:

/ / A component
class A extends Component {
    state = { count: 0 };
    add = () = > {
        this.setState({ count: this.state.count + 1 });
    };
    render() {
        return (
            <div className="a">
                <h2>A component</h2>
                <button onClick={this.add}>add</button>
                {this.props.render()}
            </div>); }}/ / Father components
export default class Father extends Component {
    render() {
        return (
            <div className="father">
                <h2>Father components</h2>
                <A render={()= > <h3>H3 tags</h3>} / ></div>); }}Copy the code

In the Father component, component A, as A child, passes A prop called render. The type is A function that returns the

tag. Render () {this.props. Render ()}}

{this.props. Render ()}} {this.props. This way, the

tag is rendered to the page.

In the code above, {this.props. Render ()} of A is like A reserved void, depending on what A’s parent passes to A. In this way, there is no need to change the logic of count for component A, just change the render passed to A, and component A dynamically renders the content that needs to be rendered.

Complete the above use case with render props:

/ / A component
class A extends Component {
    state = { count: 0 };
    add = () = > {
        this.setState({ count: this.state.count + 1 });
    };
    render() {
        return (
            <div className="a">
                <h2>A component</h2>
                <button onClick={this.add}>add</button>
                {this.props.render(this.state.count)}
            </div>); }}/ / B component
class B extends Component {
    render() {
        return <h3 className="b">B component, {this.props. Count}</h3>; }}/ / Father components
export default class Father extends Component {
    render() {
        return (
            <div className="father">
                <h2>Father components</h2>
                <A render={count= > <B count={count} />} / ></div>); }}Copy the code

The Father component passes A prop to the A component called Render, whose type is A function. The function takes a count argument, returns component B, and passes count to component B. } {this.props. Render (this.state.count)}} {this.props. Render (this.state.count)}} {this.props. The B component gets the passed count via this.props. Count and displays it on the page.

If you do not want to use component B to display, but want to use component C, then just change the render of component A in Father:

<A render={count= > <C count={count} />} / >Copy the code


The above is my humble opinion of learning, if there is anything wrong, welcome to point out the exchange!