在了解其他hook的实现后,理解useMemouseCallback的实现非常容易。

本节我们以mountupdate两种情况分别讨论这两个hook

mount

  1. function mountMemo<T>(
  2. nextCreate: () => T,
  3. deps: Array<mixed> | void | null,
  4. ): T {
  5. // 创建并返回当前hook
  6. const hook = mountWorkInProgressHook();
  7. const nextDeps = deps === undefined ? null : deps;
  8. // 计算value
  9. const nextValue = nextCreate();
  10. // 将value与deps保存在hook.memoizedState
  11. hook.memoizedState = [nextValue, nextDeps];
  12. return nextValue;
  13. }
  14. function mountCallback<T>(callback: T, deps: Array<mixed> | void | null): T {
  15. // 创建并返回当前hook
  16. const hook = mountWorkInProgressHook();
  17. const nextDeps = deps === undefined ? null : deps;
  18. // 将value与deps保存在hook.memoizedState
  19. hook.memoizedState = [callback, nextDeps];
  20. return callback;
  21. }

可以看到,与mountCallback这两个唯一的区别是

  • mountMemo会将回调函数(nextCreate)的执行结果作为value保存

  • mountCallback会将回调函数作为value保存

update

  1. function updateMemo<T>(
  2. nextCreate: () => T,
  3. deps: Array<mixed> | void | null,
  4. ): T {
  5. // 返回当前hook
  6. const hook = updateWorkInProgressHook();
  7. const nextDeps = deps === undefined ? null : deps;
  8. const prevState = hook.memoizedState;
  9. if (prevState !== null) {
  10. if (nextDeps !== null) {
  11. const prevDeps: Array<mixed> | null = prevState[1];
  12. // 判断update前后value是否变化
  13. if (areHookInputsEqual(nextDeps, prevDeps)) {
  14. // 未变化
  15. return prevState[0];
  16. }
  17. }
  18. }
  19. // 变化,重新计算value
  20. const nextValue = nextCreate();
  21. hook.memoizedState = [nextValue, nextDeps];
  22. return nextValue;
  23. }
  24. function updateCallback<T>(callback: T, deps: Array<mixed> | void | null): T {
  25. // 返回当前hook
  26. const hook = updateWorkInProgressHook();
  27. const nextDeps = deps === undefined ? null : deps;
  28. const prevState = hook.memoizedState;
  29. if (prevState !== null) {
  30. if (nextDeps !== null) {
  31. const prevDeps: Array<mixed> | null = prevState[1];
  32. // 判断update前后value是否变化
  33. if (areHookInputsEqual(nextDeps, prevDeps)) {
  34. // 未变化
  35. return prevState[0];
  36. }
  37. }
  38. }
  39. // 变化,将新的callback作为value
  40. hook.memoizedState = [callback, nextDeps];
  41. return callback;
  42. }

可见,对于update,这两个hook的唯一区别也是是回调函数本身还是回调函数的执行结果作为value