• [React] Optimization Cookbook


    Containerization of State within Child React Components

    The changing of state is the reason why components re-render. If you lift all of your state up into the parent container and pass it down to child components, any update to that state in the parent affects all other sibling components. Causing many useless re-renders. By simply moving the state into that child component, saves having to use React.Memo on all sibling components.

    function Parent () {
        const [count, setCount] = useState(0);
        
        return (
            <>
                <Child count={count} setCount={setCount} />
                <SecondChild />
                <ThirdChild />
            </>
        )
    }
    
    function Child({count, setCount}) {
        ...
    }

    We lift Child component state to its Partent component, then passing the props down to the Child component. 

    ‍♀️ This is not a good solution, if the state changed (count), it will cause all the children components (Child, SecondChild, ThridChild) re-render; And SecondChild, ThirdChild have nothing todo with `count` state.

    Containerization the state to its component:

    function Parent() {
        return (
            <>
                <Child />
                <SecondChild />
                <ThirdChild />
            </>
        )
    }
    
    function Child() {
     const [count, setCount] = useState(0)
     
     return (...)
    }

    Now, if the count changes, it only re-render Child component, doesn't affect other components.

    Optimize Function Components with React.memo

    React.memo is similar to PureComponent when working with class components. This feature new to React 16 will not allow a functional component to render if its props hasn’t changed.

    • It only works for functional component
    • React.memo do shadow comparsion, If the component props is nested object, then React.memo won't do deep comparsion.
    • You can pass in a custom comparsion function into React.memo
    • If the wrapped component has `useState`, `useReducer` or `useContext`, the component will re-render.

    Memoized Values with React useMemo

    useMemo is a handy hook that we can use to avoid unnecessary computations of expensive functions. useMemo will only recompute the memorized value returned from the first parameter (called the create function) when a dependency in the second parameter array changes. Thus saving our app from re-computing a function each time our component re-renders.

    • It works the computed value
    const topProduct = React.useMemo(
        () => data.sort((a, b) => b.progress - a.progress)[0], []
    )

    Memoize a Function with useCallback in React

    The useCallback hook returns a memoized callback. To be more specific, useCallback will return a memorized version of the callback that only changes if one of the dependencies passed in the second parameter array has changed. This is particularly useful when working with optimized components and to goal is to avoid unnecessary re-renders, due to prop changes.

    When you pass function into Child component, React consider, each time function is a new function... so it will re-render the component.

    • It works for wrap a function which need to be passed to a child component
    const CountButton = React.memo(function CountButton({ onClick, count }) {
      console.log("CountButton Rendered");
      return <button onClick={onClick}>{count}</button>;
    });
    
      const [count1, setCount1] = React.useState(0);
      const likeIncrement = React.useCallback(() => setCount1((c) => c + 1), []);
    
      const [count2, setCount2] = React.useState(0);
      const dislikeIncrement = React.useCallback(() => setCount2((c) => c + 1), []);
    
      <CountButton count={count1} onClick={likeIncrement} />
      <CountButton count={count2} onClick={dislikeIncrement} />

    Without, useCallback, you click on either Like or Dislike button, both buttons will be re-render, with useCallback, it will only re-render one.

    Add the why-did-you-render Package to Catch Unnecessary Updates in React

    Sometimes it can be difficult to understand why your components are rerendering. The why-did-you-update package will show what props and/or state updated that cause the re-render. Let’s install this package and figure out why our component is unnecessarily updating.

    https://github.com/welldone-software/why-did-you-render

    Code Split Components with React Lazy & Loadable Components

    Code splitting is the process in which you only send to the browser the files necessary to render the current page. Instead of sending the entire app and all of its resources for all pages. Today there are many different ways to accomplish this React.lazy and Loadable Components.

    https://reactjs.org/docs/code-splitting.html#reactlazy

    https://github.com/gregberge/loadable-components

    Using react lazy:

    const Dashboard = react.lazy(() => import('./pages/Dashboard/Dashboard.js'))
    • React lazy doesn't work with Server side rendering

    Using loadable

    import loadable from "@loadable/component"
    
    const Dashboard = loadable(() => import("./pages/Dashboard/Dasjbpard.js"))
    • Works with SSR
  • 相关阅读:
    Logistic回归
    朴素贝叶斯
    决策树
    K-邻近(KNN)算法
    快速排序
    归并排序
    希尔排序
    插入排序
    选择排序
    浅谈系统服务分发
  • 原文地址:https://www.cnblogs.com/Answer1215/p/16218487.html
Copyright © 2020-2023  润新知