• The container mode
    • Implement conditional execution of Hooks
    • Reuse UI logic using the Render props pattern

First, an important rule for Hooks: Hooks must be called in the top-level scope, not in conditional, loop statements, that is, Hooks must be executed.

This rule exists because React needs to maintain the Hooks state used within function components

For example, for a dialog box component, the visible property is used to control whether it is displayed.

For example, the expectation is as follows:

function UserInfoModal({ visible, userId, ... rest }) {

    if(! visible)return null

    const [data, loading, error] = useUser(userId)

    return (

        <Modal visible={visible} {. rest} >

        </Modal>)}Copy the code

As you can see, we expect not to display the content when visble is false, but this will fail to compile because the useUser hook comes after the return statement.

Therefore, we need an indirect implementation of conditional logic using the container pattern

To do this, add a conditional judgment to both components

Add a container around UserInfoModal

export default function UserInfoModalWrapper ({ visible, ... rest//Use REST to get all attributes except visible}) {
    if(! visible)return null
    return <UserInfoModal {. rest} / >
}
Copy the code

Put the conditions of judgment in Hooks

In container mode we can see that conditional isolation objects are sub-components, which means that they are used for large logical isolation. For details of control, put them directly in Hooks. For example, get the author after the article gets it.

  • Use render props mode (that is, pass render as props)
    • React is one of the most important design patterns that addresses the reuse of UI logic
    • This applies not only to Class components but also to function components

You pass a render function as a property to a component that executes the function to render the actual content.

In function components, Hooks have the limitation that they can only be used for reuse of data logic. For reuse of UI presentation logic, use render props.

First, implement a simple example of data logic reuse:

import { useState, useCallback } from 'react'

function CounterRenderProps({ children }) {

    cosnt [count, setCount] = useState(0)

    const increment = useCallback(() = > {

        setCount(count+1)

    }, [count])

    const decrement = useCallback(() = > {

        setCount(count-1)

    },[count])

    return children({ count, increment, decrement })

}

function CounterRenderPropsExample() {

    <CounterRenderProps>

        {

            ({ count, increment, decrement } => {

                return (

                        <div>

                            // ...

                        </div>

                    )

            })

        }

    </CounterRenderProps>

}
Copy the code
  • There are examples of UI logic reuse

    1. For example, we need to display a list, and if there are more than a certain number, fold the extra parts and display them in a pop-up box.
    2. Implement a table that also shows the first five and folds the excess into more inside.

Analyze:

The same part of the function is that when the data exceeds a certain amount, a more text will be displayed. When the mouse moves up, a box will pop up for displaying other data

Functional differences: How each list item is rendered is determined as it is used.

import { Popver } from 'antd'

function ListWithMore({ renderItem, data=[], max }) {
    const elements = data.map((item, index) = > renderItem(item, index, data))
    const show = elements.slice(0,max)
    const hide = elements.slice(max)
    return (
        <span>
            {show}
            {
             hide.length > 0 && (
                 <Popver>
                     <span>
                         and {" "}
                         <span>{hide.length} more...</span>
                     </span>
                 </Popver>)}</span>)}Copy the code

As you can see, the component receives three parameters:

  1. RenderItem: Receives a function that lets the parent component decide how to render a list item;
  2. Data: data to render;
  3. Max: Displays a maximum of several pieces of data.

The following code shows the implementation code for the two scenarios in the diagram above: