preface

The React source reference version is 17.0.3. This is the React source series second, it is recommended that first look at the source of the students from the first to see, so more coherent, there are source series links below.

The warm-up to prepare

UseCallback and useMemo are the same thing, but the input is different.

UseCallback caches the callback function. If the dependency is not updated, the cached callback function is used.

UseMemo caches the return of the callback function. If the dependency has not been updated, the cached return is used.

UseCallback (fn, deps) useMemo(() => fn, deps)

So here, we will only analyze useCallback as an example.

Initialize the mount

mountCallback

If you started with the first article in the series, there’s probably no pressure to see this. MountCallback is just a few lines of code, and I didn’t simplify it.

Var hook = mountWorkInProgressHook(); var hook = mountWorkInProgressHook(); Var nextDeps = deps === undefined? null : deps; / / will be in the form of an array callbacks and rely on the fiber array to store. MemoizedState. J hook. MoeoizedState hook. MemoizedState = [callback, nextDeps]; return callback; }Copy the code

Update the update

function updateCallback(callback, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; var prevState = hook.memoizedState; if (prevState ! == null) { if (nextDeps ! == null) { var prevDeps = prevState[1]; if (areHookInputsEqual(nextDeps, prevDeps)) { return prevState[0]; } } } hook.memoizedState = [callback, nextDeps]; return callback; }Copy the code

UpdateCallback is just a few lines of code, no cuts, and the intent is very simple, if the dependency array deps hasn’t changed, or if deps=[], it will return the cached callback function, Otherwise, update the corresponding fiber. MemoizedState. Hook. MemoizedState and returns a new callback function.

Usage scenarios

As far as I can see, there are two extreme cases. One is that developers like to use useCallback and useMemo for all functions and data. Another developer that wouldn’t consider using useCallback under any circumstances is useMemo.

Needless to say, both approaches are problematic. In the first way, it is not known whether this problem occurs, but the root cause is that many developers do not understand the principles and usage scenarios of these two hooks.

First, we need to make it clear that the function component is executed every time it is updated, and that all the methods and values inside the function component are redeclared and recalculated. The appearance of these two hooks is to optimize this situation and avoid unnecessary waste. And it is these two hooks by function or value stored in the corresponding fiber. The memoizedState. J hook. MemoizedState, in the next update, according to whether the dependency changes to decide whether to use the cache value, or new incoming values.

At this point, some people may wonder why it’s so bad for me to wrap it all up since it’s all going to be updated. In my opinion, the main problem with all wrapping is that if a function is simple enough, the performance cost of redeclaring it may be less than that of storing it in hook. MemoizedState after wrapping it.

Here, the author lists the use scenarios of these two hooks based on his own experience in looking at the source code:

  1. If the child component is more complex, consider using ituseCallbackTo package;
  2. If a value in a function component requires a lot of computation, consider using ituseMemoTo package;
  3. If a function is the props of a child component, consider using ituseCallbackCarry out the package (cooperateReact.memoUse);
  4. The customhooksComplex logic can be considereduseCallbackanduseMemoTo package;

conclusion

The two hook principles are still very simple. Since they are series of articles, many contents have been repeated from the previous articles, so there is nothing to write in this article. To summarize the principles:

It is these two hooks by function or value stored in the corresponding fiber. The memoizedState. J hook. MemoizedState, in the next update, according to the dependency to decide whether change is to use the cache value, or new incoming values.

Although useCallback and useMemo are used to optimize performance, you should not blindly use them, after all, the two hooks themselves will bring costs.

After reading this article, we can understand the following questions:

  1. useCallbackanduseMemoThe difference between?
  2. useCallbackanduseMemoWhat are the use scenarios of the
  3. useCallbackanduseMemoWhat does it do?
  4. useCallbackanduseMemoHow is performance optimized?

Article series arrangement:

  1. React Fiber;
  2. React source series 2: React rendering mechanism;
  3. React source series 3: hooks useState, useReducer;
  4. React code series 4: hooks useEffect;
  5. React code Series 5: Hooks useCallback, useMemo;
  6. React source Series 6: Hooks useContext;
  7. React source series 7: React synthesis events;
  8. React source series eight: React diff algorithm;
  9. React source series 9: React update mechanism;
  10. React source series 10: Concurrent Mode;

Reference:

React official documents;

Making;