react hooks 源码学习记录

  • 时间:
  • 浏览:
  • 来源:互联网

useEffect

问题一:
为什么在dep没有改变的情况下,不走useEffect的回调,原理是什么?
看一个简单的例子:

import * as React from "react";
import * as ReactDOM from "react-dom";

import {Component, useState, useEffect} from "react";

export default class ClassFunctionComponent extends Component {
  render() {
    return (
      <div>
        <h3>ClassFunctionComponent</h3>
        <FunctionComponent />
      </div>
    );
  }
}
function FunctionComponent(props) {
  const [count, setCount] = useState(0);
  const [val, setVal] = useState("");

  const add = () => {
    setCount(count + 1);
  };
  useEffect(() => {
    debugger
    console.log("useEffect", count); //sy-log
  }, [count]);

  const handleChange = e => {
    setVal(data => e.target.value);
  };
  return (
    <div className="border">
      <h3>FunctionComponent</h3>
      <p>{count}</p>
      <button onClick={add}>add</button>
      <input type="text" value={val} onChange={handleChange} />
    </div>
  );
}

useEffect在源码中调用的是
src/react/packages/react-reconciler/src/ReactFiberHooks.old.js

function mountEffectImpl(fiberFlags, hookFlags, create, deps): void {
  const hook = mountWorkInProgressHook();
  const nextDeps = deps === undefined ? null : deps;
  currentlyRenderingFiber.flags |= fiberFlags;
  hook.memoizedState = pushEffect(
    HookHasEffect | hookFlags,
    create,
    undefined,
    nextDeps,
  );
}

function updateEffectImpl(fiberFlags, hookFlags, create, deps): void {
  const hook = updateWorkInProgressHook();
  const nextDeps = deps === undefined ? null : deps;
  let destroy = undefined;

  if (currentHook !== null) {
    const prevEffect = currentHook.memoizedState;
    destroy = prevEffect.destroy;
    if (nextDeps !== null) {
      const prevDeps = prevEffect.deps;
      if (areHookInputsEqual(nextDeps, prevDeps)) {
        pushEffect(hookFlags, create, destroy, nextDeps);
        return;
      }
    }
  }
  currentlyRenderingFiber.flags |= fiberFlags;
  hook.memoizedState = pushEffect(
    HookHasEffect | hookFlags,
    create,
    destroy,
    nextDeps,
  );
}

对于依赖没有改变的情况,不需要挂到hook.memoizedState上,只是执行了pushEffect,只有在依赖变化时候,pushEffect的参数才会带上hookHasEffect去执行后续

本文链接http://www.dzjqx.cn/news/show-617533.html