HOC: The most classical way of logic reuse of components

HOC is an advanced technique used in React to reuse component logic. HOC itself is not part of the React API; it is a design pattern based on the composite features of React. – the React official

A higher-order component concept is similar to a higher-order function: a class of functions that receive a function as input or output another function are higher-order functions.

A higher-order component, in turn, is a function that takes a component and returns a new component. Yes, a higher-order component is essentially a function, for example:

function withProps (WrappedComponent) {

    function targetComponent (props) (

        <div className="wrapper-container"> <WrappedComponent {... props} /> </div>);

    return targetComponent;

};

Copy the code

How to reuse logic through higher-order components, a simple example

    function checkUserAccess(){
        // ...
    }
    function CheckAccess(component){
        const isValid = checkoutUserAccess();
        return <component isValid={isValid}/>
    }
Copy the code

With higher-order components, additional capabilities can be provided to encapsulate this part of logic

Render Props: Another way of thinking about logic reuse

The term “Render Prop” refers to a simple technique for sharing code between React components using a prop with a value of function. – the React official

Render props is another way to reuse component logic in React. It is implementation-wise similar to higher-order components — both are extracting common logic into one place. The difference is mainly in the use layer. The use posture of higher-order components is “function” wrapped around “component”, whereas the render props are the opposite, emphasizing “component” wrapped around “function”.

for example:

    function RenderChildren(props){
        return (
        <>
        {props.children(props)}
        </>)}Copy the code

There are two points:

  1. The carrier of render props should be a React component, as opposed to higher-order components (which are essentially functions);

  2. The Render props component works only if its child components need to exist as functions.

The first point is easier to understand, mainly the second: let’s look directly at how render props are used

<RenderChildren>         
  {() = > <p>I'm a child of RenderChildren</p>}       
</RenderChildren>
Copy the code

This is different from the react component we usually write

<RenderChildren>         
  <children/>     
</RenderChildren>
Copy the code

In the render props mode, however, it requires that the function wrapped in the render props component tag be a function, so that the function is passed in as a child component. Thus, the Render props component can communicate with the target component by calling this function and passing the props.

How do render props implement logic reuse? Here’s an example, again using getAccess

   function checkUserAccess(){
        // ...
    }
    function CheckAccess(props){
        const isValid = checkUserAccess();
        return (
            <>{ props.children({... props,isValid}) }</>)}/ /...
    <CheckAccess>
    {
        (props) = > {
        const { isAccessible } = props;
        return <ChildComponent {. props} isAccessible={isAccessible} />
            
        }
    }
    </CheckAccess>
Copy the code

Of course, this does not mean that the function is passed as children, as long as it is any function name that can be received by the Render props component

function checkUserAccess(){ // ... } function CheckAccess(props){ const isValid = checkUserAccess(); return ( <> { props.targetComponent({... props,isValid}) } </> ) } //... <CheckAccess targetComponent = { (props) => { const { isAccessible } = props; return <ChildComponent {... props} isAccessible={isAccessible} /> } } > </CheckAccess>Copy the code

What’s so special about render props compared to HOC?

Render props would be a better choice for you because it’s more flexible

A very important difference between render props and higher-order components lies in the processing of data: in higher-order components, the target component has no initiative to obtain data, and the data distribution logic converges inside the higher-order components. In the render props, in addition to the parent component distributing data, the child component can optionally receive data.

For example: We now have a NewComponent that also needs to be authenticated, but due to historical reasons, this component cannot accept isValid, only isAccess, so if we use HOC, we need to handle the wrapping function:

    function checkUserAccess(){
        // ...
    }
    function CheckAccess(component){
        const isValid = checkoutUserAccess();
        if(component.displayName === 'newComponent') {return <component isAccess={isValid}/>
        }
        return <component isValid={isValid}/>
    }
Copy the code

And the same thing. The mode of render props, we just need to change to

    // ...  
    <CheckAccess
        targetComponent = {
            (props) = > {
                const { isValid } = props;
                return <ChildComponent {. props} isAccess={isValid} />
            }
        }
    >
    </CheckAccess>
Copy the code

In fact, there is a very important principle in software design patterns called the “open closed principle”. A good model should be as open as possible to expansion and closed to modification.

With the same requirements, render props were able to help us with the “open and closed” principle.