directory

  • directory
  • The body of the
    • useEffect
    • useCallback
    • useRef
    • useMemo
    • useLayoutEffect
    • skills
    • Matters needing attention
  • teasing
  • The resources

The body of the

useEffect

  • A common mistake to make is to think of Hooks in terms of the life cycle of class-style components. Such as:

    useEffect(() = > { fetchList() }, []); // Use this method to simulate the loading event
    Copy the code

    This will work if the fetchList stays the same throughout use, but if the function changes, the above code will have a problem. So what’s the solution?

    // The first method is to add corresponding dependencies
    useEffect(() = > { fetchList() }, [fetchList]);
    Copy the code

    But instead of having to load once initially, you can use the second method

    // The second method is to use useCallback
    constfetchList = useCallback(... []); useEffect(() = > { fetchList() }, [fetchList]);
    Copy the code

    But what if fetchList itself has dependencies?

    // Use usePersistFn
    constfetchList = usePersistFn(...) ;// The parameters used in the method will change
    useEffect(() = > { fetchList() }, [fetchList]);
    Copy the code
    // Create a Ref reference to fetchList
    const fetchListRef = useRef(fetchList);
    fetchListRef.current = fetchList
    useEffect(() = >{ fetchListRef? .current() });Copy the code

    I just want to solve the problem of loading, is there a simpler one?

    // The fifth way is to write the function inside useEffect
    useEffect(() = > {
      const fetchList = (query) = > {};
      fetchList(props.query)
    }, [])
    Copy the code
    // The sixth method, useMount
    useMount(() = > { fetchList() })
    Copy the code

    With regard to the dependency problem, it is suggested thateslint-plugin-reactTurn it on. You can avoid a lot of mistakes

  • Do not write a lot of irrelevant logic in a single set of hooks. This avoids having too many dependencies that update the entire set of hooks, adding overhead

    // bad
    useEffect(() = > {
      // A depends on A, b
      A, B, C,d
    }, [a, b, c, d])
    
    // good
    useEffect(() = > {
      // A depends on A, b
    }, [a, b])
    useEffect(() = > {
      A, B, C,d
    }, [c, d])
    Copy the code
  • Interfaces such as get data can be written outside the component, if not specifically required, or inside hooks

    // bad
    const Example = props= > {
      // ...
      const foo = (params) = > {};
      useEffect(() = > {
        foo(params)
      }, [foo, params])
    };
    
    // good
    const _foo = (params) = > {}; // Write outside the component
    const Example = props= > {
      // ...
      useEffect(() = > {
        _foo(params)
      }, [params])
    };
    Copy the code
  • You can use useRef or useReducer to manage data that does not need to be added to the database or that requires a large amount of calculation

    const bigDataRef = useRef(/* Initial value */)
    useEffect(() = > {
      // bigDataRef.current
    }, [])
    Copy the code
    const [state, dispatch] = useReducer((state, action) = > {
      switch (action.type) {
        case 'plus':
          return { ...state, count: state.count + 1};
        default:
          returnstate; }}, {count: 0 });
    
    useEffect(() = > {
      console.log(state.count)
    }, [])
    Copy the code
  • When updating or uninstalling components, remember that side effects functions, such as timers, do not complete asynchronous requests (which can be cancelled with the useRequest method in Ahooks)

    I have suffered this kind of loss in multi-tabbed style background projects. Some callbacks are applied to the new TAB page because the side effects of cutting the TAB are not cleared in time.

    const { data, run, cancel } = useRequest({ manual: true });
    useEffect(() = > {
      run()
      return () = > {
        cancel()
      }
    }, [data, run, cancel])
    Copy the code

useCallback

  • Reference scenarios need to be compared, such as useEffect, or used with react.Memo (code reference)
  • What can be written outside the component is written outside the component
  • Not every situation should use useCallback, useCallback itself has some performance loss, okay
  • Use useCallback. Use useCallback

useRef

  • Properties that change frequently and are not strongly dependent, use useRef

  • In the ahooks project, we found that basically every argument of type Function uses Ref

    // useInterval
    // ...
    const fnRef = useRef<() = > void> (); fnRef.current = fn;// ...
    Copy the code

useMemo

  • The useMemo part of the scenario can be used as a computed object in vUE, which is commonly used in places where there is a lot of computation

useLayoutEffect

  • Use this when your useEffect operations need to work with the DOM and change the style of the page, otherwise you may have flash screen problems

skills

  • Components of a property if it is dom, want to consider whether Ref | Function dom | | the Selector type, etc
    • GetTargetElement fine with this Function, can get Ref | Function | Dom corresponding Dom node type
  • When solving state synchronization problems, arguments like setState may bevalueOr it could befunction. It may also be used when encapsulating your own components
  • If you want to inject default parameters, it will be used in multiple places. You can usecreateXXX({... params}) => useXXX; useXXX()This form
  • The first reducer parameter of useReducer does not have to have a strict specification installed, but can be similarconst toggleReducer = (state, nextValue) => (typeof nextValue === 'boolean' ? nextValue : ! state);. To achieve the same effect as ref in data processing

Matters needing attention

  • Enable eslint: eslint-plugin-react
  • If an asynchronous update occurs in a function, such as setTimeout, Promise. In addition, multiple values may be triggered in a short period of time, and value errors may occur
  • Hooks if there areasynchronousRequests, to ensure that each result of the latest, and old requests or results are removed

teasing

Because of the need of the new job, efforts to make up React foundation. At present, I have only learned React for three months, and I am still not familiar with it. Fortunately, some seniors have given me guidance, so I have made few detours.

The current project is basically based on Hooks. Because the basic skills are not solid, also made a few mistakes, look at other people’s code also found a lot of wrong usage, so where insufficient where. Checked out the hooks library on the market to learn from someone else’s code. And made these conclusions.

Unexpected experience.

This study source code has an interesting place. While looking at the source code, open Git History and go through the iteration History to see how they did it in the first place and how they changed to the current version. Don’t take the current version for granted; you’ll probably make the same mistakes again by the time you play.

Hooks have many more tricks and problems, keep them fixed when new ones are found.

The resources

  • ahooks
  • How to fetch data with React Hooks?
  • Use React Hooks to declare setInterval
  • UseEffect complete guide
  • The React Hooks,
  • A summary of five large project practices, decipher React Hooks best practices