React

组件中的函数

由于hooks的引入,函数(useCallback)可以作为依赖了,但是这种依赖在 组件使用者 - 组件开发者 这样的关系中是不可靠的。因为 useCallback 使得函数本身可作为依赖,这就导致了,函数只会在 组件使用者 让他变的时候会变,或者是,组件使用者随时可以让他变,然而在组件开发中,函数的调用,这个控制权,大多数时候是应该完全掌握在 组件开发者 手中的。
所以组件中的函数导致的 1. 无限调用 2. 函数陈旧 … 等问题,归根结底是传入组件的函数被组件内部未管制的依赖控制了,也就是外部使用者传递了不纯的函数。
为了组件内部实现对 外部函数的完全控制,应该避免外部传入 useCallback,或不可用 外部函数 作为内部 hook 的依赖,也就是假定 外部函数,必定是无效依赖。这样得以保证外部函数的纯度(pure)。
同理,为了减轻副作用,或减少副作用带来的脏值检查,组件的 props,应尽量保证只使用基本类型,引用类型即使使用,也是使用引用内部的基本类型属性,使得组件内部使用外部的依赖,基本无副作用(不会被意外篡改,且篡改后不被响应)。剩余的必要引用类型,要么做纯数值,随取随用(不做 useEffect 依赖),要么脏值检查手动生成为有效依赖。

debounce 尾调用(review)

利用 useEffect 每次render后的 return 触发 clearTimeOut,可以让 useEffect 中的调用,始终保持在频繁 render 的末尾,注意⚠️ 若当前 effect 内部最终触发的 setState,会再次出发 useEffect,可能就会造成死循环,所以存在这种情况,则需要 setState 时判断值是否改变,未改变则放弃rerender。

  1. export const A: React.FC<{
  2. other: number
  3. }> = ({ other }) => {
  4. const [state, setState] = React.useState(0);
  5. React.useEffect(() => {
  6. const timer = setTimeout(() => {
  7. setState((curState) => {
  8. // ... computed other & curState
  9. if (changed) {
  10. return computed
  11. }
  12. return curState
  13. });
  14. }, 200);
  15. return () => {
  16. clearTimeout(timer);
  17. };
  18. }, [other]);
  19. return null;
  20. }