create-your-own-react笔记

120 阅读2分钟

github 仓库链接

乱七八糟的想法

  1. requestIdleCallback

答:react实现自己的Scheduler替代浏览器原生的ric

  1. 浏览器一帧干啥

答:主线程->requestAnimationFrame->渲染线程->ric

  1. setState有批处理么

答:setState是把action推到queue里面了,下一轮useState的时候for迭代去更新

  1. 组件、element、fiber、node

答:element:react虚拟dom
fiber:高级element
node:真实dom
这组件指函数组件,只有他可以createElement去刷新element

  1. 任何的state,不管在哪里的state,变化了,都会重新生成fiber树么?element树要重新生成?他们俩的重新生成的关系是什么

答:(1)是的。只要有state变化了,操作都是一样的。管他三七二十一,设置nextUnitWork为一个新的fiber。至于这个fiber什么时候开始织,看sheduler安排时间(已经不用浏览器原生RIC)。

const setState = (action) => {
    hook.queue.push(action);

    wipRoot = {
      dom: currentRoot.dom,
      props: currentRoot.props,
      alternate: currentRoot,
    };
    nextUnitOfWork = wipRoot;
    deletions = [];
  };

(2)element树变不变,这么去想,element树只有createElement调用的时候会变,那CE函数什么时候会调用,就是检测到当前wipFiber为FunctionComponent而不是HostComponetnt,就会重新生成element。
(3)不是先生成一个新的element树,然后拿新elemnt树和旧fiber树去对比,而是从wipRoot一点一点生成,去对比,这个过程叫reconcile

  1. 什么样的fiber才有alternate,还是说都有

答:wipRoot和curd中的u(type相同,update)

  1. 对于element,是不是就应用第一开始有用?

答:如果是纯HostComponent,是的。element树不会变

  1. 为什么组件只能有一个根节点,<>这个又是什么

答:因为在组件中需要return,return返回一个东西。<>是<React.Fragment>

  1. 每一个组件函数都是一个 fiber,组件的 fiber 有一个 hooks 数组,维护所有的 hooks

例子:

function ComplexComponent() {
  const [count, setCount] = useState(0);                    // hook[0]
  const [user, setUser] = useState({ name: '张三' });      // hook[1]
  
  const userRef = useRef(null);                            // hook[2]
  
  const handleClick = useCallback(() => {                   // hook[3]
    setCount(c => c + 1);
  }, []);
  
  useEffect(() => {                                        // hook[4]
    console.log('count changed:', count);
  }, [count]);
  
  const memoizedValue = useMemo(() => {                    // hook[5]
    return count * 2;
  }, [count]);

  return <div>...</div>;
}

hooks的结构如下:

fiber.hooks = [
  {
    // useState hook for count
    state: 0,
    queue: [] // 状态更新队列
  },
  {
    // useState hook for user
    state: { name: '张三' },
    queue: []
  },
  {
    // useRef hook
    memoizedState: {
      current: null
    }
  },
  {
    // useCallback hook
    memoizedState: {
      callback: () => { setCount(c => c + 1) },
      deps: [] // 空依赖数组
    }
  },
  {
    // useEffect hook
    effect: {
      create: () => { 
        console.log('count changed:', count);
        return () => { /* cleanup */ };
      },
      deps: [0], // count的当前值
      destroy: undefined // 清理函数
    }
  },
  {
    // useMemo hook
    memoizedState: {
      value: 0, // 计算结果
      deps: [0] // count的当前值
    }
  }
];