一、useState
    自定义一个立即执行函数:ReactX

    1. const ReactX = (() => {
    2. let state;
    3. const useState = (initialValue) => {
    4. if (state == undefined) {
    5. state = initialValue;
    6. }
    7. const setterFunction = (newValue) => {
    8. state = newValue;
    9. }
    10. return [state, setterFunction];
    11. };
    12. return {
    13. useState,
    14. }
    15. })();

    使用useState:

    1. const Component = () => {
    2. const [counterValue, setCounterValue] = useState(1);
    3. console.log(counterValue);
    4. if (counterValue !== 2) {
    5. setCounterValue(2);
    6. }
    7. };
    8. Component(); // 1
    9. Component(); // 2

    二、升级useState
    真实的state是array的形式:

    1. let hooks = [];
    2. let index = 0;
    3. const useState = (initialValue) => {
    4. const localIndex = index;
    5. index++;
    6. if (hooks[localIndex] == undefined) {
    7. hooks[localIndex] = initialValue;
    8. }
    9. const setterFunction = (newValue) => {
    10. hooks[localIndex] = newValue;
    11. }
    12. return [hooks[localIndex], setterFunction];
    13. };

    此时运行:

    1. Component(); // 1
    2. Component(); // 1

    结果变成:
    image.png
    会发现值没有更新,因此需要一个新的resetIndex函数:

    1. const resetIndex = () => {
    2. index = 0;
    3. }

    然后再次使用即可得到预期结果:

    1. const { useState, useEffect, resetIndex } = ReactX;
    2. const Component = () => {
    3. const [counterValue, setCounterValue] = useState(1);
    4. if (counterValue !== 2) {
    5. setCounterValue(2);
    6. }
    7. console.log('counterValue', counterValue);
    8. };
    9. Component(); // 1
    10. resetIndex();
    11. Component(); // 2

    此时hooks的arr里只有一个值,即为最新值:
    image.png
    三、useEffect
    useEffect需要根据传入的依赖是否改变而判断是否需要更新值:

    1. const useEffect = (callback, dependencyArray) => {
    2. let hasChanged = true;
    3. const oldDependencies = hooks[index];
    4. if (oldDependencies) {
    5. hasChanged = false;
    6. dependencyArray.forEach((dependency, index) => {
    7. const oldDependency = oldDependencies[index];
    8. const areTheSame = Object.is(dependency, oldDependency);
    9. if (!areTheSame) {
    10. hasChanged = true;
    11. }
    12. });
    13. }
    14. if (hasChanged) {
    15. callback();
    16. }
    17. hooks[index] = dependencyArray;
    18. index++;
    19. }

    使用useEffect同样需要需要resetIndex,否则useEffect的callback函数会重复被调用:

    1. const { useEffect, resetIndex } = ReactX;
    2. const Component = () => {
    3. useEffect(() => {
    4. console.log("useEffect");
    5. }, []);
    6. };
    7. Component();
    8. resetIndex();
    9. Component();

    结果:
    image.png
    源码:https://github.com/bbcfive/react-hooks-demo/blob/main/ReactX.js
    参考视频:https://www.youtube.com/watch?v=1VVfMVQabx0