一、useState
自定义一个立即执行函数:ReactX
const ReactX = (() => {let state;const useState = (initialValue) => {if (state == undefined) {state = initialValue;}const setterFunction = (newValue) => {state = newValue;}return [state, setterFunction];};return {useState,}})();
使用useState:
const Component = () => {const [counterValue, setCounterValue] = useState(1);console.log(counterValue);if (counterValue !== 2) {setCounterValue(2);}};Component(); // 1Component(); // 2
二、升级useState
真实的state是array的形式:
let hooks = [];let index = 0;const useState = (initialValue) => {const localIndex = index;index++;if (hooks[localIndex] == undefined) {hooks[localIndex] = initialValue;}const setterFunction = (newValue) => {hooks[localIndex] = newValue;}return [hooks[localIndex], setterFunction];};
此时运行:
Component(); // 1Component(); // 1
结果变成:
会发现值没有更新,因此需要一个新的resetIndex函数:
const resetIndex = () => {index = 0;}
然后再次使用即可得到预期结果:
const { useState, useEffect, resetIndex } = ReactX;const Component = () => {const [counterValue, setCounterValue] = useState(1);if (counterValue !== 2) {setCounterValue(2);}console.log('counterValue', counterValue);};Component(); // 1resetIndex();Component(); // 2
此时hooks的arr里只有一个值,即为最新值:
三、useEffect
useEffect需要根据传入的依赖是否改变而判断是否需要更新值:
const useEffect = (callback, dependencyArray) => {let hasChanged = true;const oldDependencies = hooks[index];if (oldDependencies) {hasChanged = false;dependencyArray.forEach((dependency, index) => {const oldDependency = oldDependencies[index];const areTheSame = Object.is(dependency, oldDependency);if (!areTheSame) {hasChanged = true;}});}if (hasChanged) {callback();}hooks[index] = dependencyArray;index++;}
使用useEffect同样需要需要resetIndex,否则useEffect的callback函数会重复被调用:
const { useEffect, resetIndex } = ReactX;const Component = () => {useEffect(() => {console.log("useEffect");}, []);};Component();resetIndex();Component();
结果:
源码:https://github.com/bbcfive/react-hooks-demo/blob/main/ReactX.js
参考视频:https://www.youtube.com/watch?v=1VVfMVQabx0
