pomber / didact

A DIY guide to build your own React
https://pomb.us/build-your-own-react/
6.29k stars 531 forks source link

Adding useEffect hook #48

Open zbzalex opened 1 year ago

zbzalex commented 1 year ago
  1. add global variable

    let pendingEffects = []
  2. cerate a hook and add effects tag

    function useEffect(fn, deps) {
            const hook = {
                tag: "EFFECT",
                fn,
                deps,
            }
    
            wipFiber._hooks.push(hook)
            hookIndex++
    }
  3. modify performUnitOfWork function

    if (isFunctionComponent) {
    ...
    Object .keys(wipFiber._hooks)
                    .filter(hookIndex => wipFiber._hooks[hookIndex].tag === "EFFECT")
                    .forEach(hookIndex => {
                        const oldHook =
                            wipFiber.alternate &&
                            wipFiber.alternate._hooks &&
                            wipFiber.alternate._hooks[hookIndex]
    
                        const hook = wipFiber._hooks[hookIndex]
                        const depsChanged = (prev, next) => (_, index) => prev[index] !== next[index];
                        if (hook.deps.length === 0 && !oldHook
                            || oldHook && (oldHook.deps.length !== hook.deps.length
                                || oldHook && hook.deps.filter(depsChanged(oldHook.deps, hook.deps)).length !== 0)) {
                            pendingEffects.push(hook.fn)
                        }
                    })
    ...
  4. go to commitRoot function

...
pendingEffects.forEach(it => it()) // call pending effects after render
zbzalex commented 1 year ago

Modification project https://github.com/zbzalex/react-lite