< Back

React Hook简易版

先创建一个useState的hook,都知道这个hook会返回一个数组,包含当前值和一个改变值的函数。

const ReactX = (() => { const useState = (initialValue) => { let state = initialValue; const setterFunction = (newValue) => { state = newValue; } return [state, setterFunction]; } return { useState, } })();

然后创建一个组件,并使用useState,然后改变state。

const Component = () => { const [counterValue, setCounterValue] = useState(1); console.log(counterValue); if (counterValue !== 2) { setCounterValue(2); } }

因为state改变后会触发渲染,所以这里通过再调用一次Component函数来模拟重新渲染。

Component(); // 1 Component(); // 1

会输出两个1,重新渲染没能保持state的正确,原因也很简单,因为每次调用Component都时候,useState重新执行,然后创建新的state。要解决这个问题,得把state移动到useState外面去,这样就能保证每次useState调用都是引用同一个state。

const ReactX = (() => { let state; const useState = (initialValue) => { state = initialValue; const setterFunction = (newValue) => { state = newValue; } return [state, setterFunction]; } return { useState, } })();

但是这样依然不行,因为每次都会被initialValue给重置了,因此要保证只被初始化一次。加个条件即可。这样就能输出1,2了。

const ReactX = (() => { let state; const useState = (initialValue) => { if (state === undefined) { state = initialValue; } const setterFunction = (newValue) => { state = newValue; } return [state, setterFunction]; } return { useState, } })();

这个时候的问题是只能只用一个state,如果要使用多个,那自然就会想到数组。

const ReactX = (() => { let state = []; let index = 0; const useState = (initialValue) => { const localIndex = index; index++; if (state[localIndex] === undefined) { state[localIndex] = initialValue; } const setterFunction = (newValue) => { state[localIndex] = newValue; } return [state[localIndex] , setterFunction]; } const resetIndex = () => { index = 0; } return { useState, resetIndex } })();

将state变成数组,并且加上index,使得可以利用useState来创建多个state。并且重新渲染的时候记得重置index。

Component(); resetIndex(); Component();

到目前为止就能回答那个问题:为什么hook不能在条件语句中调用?,因为重新渲染的时候可能导致这些个index和hook不匹配。

hook遵循两条规则:

  • 便于组合,hook之间不会互相冲突
  • 便于调试,容易发现bug

可以根据这两点来判断某个useXXX是不是真的hook。

整理自:https://www.youtube.com/watch?v=1VVfMVQabx0&t=97s&ab_channel=PhilipFabianek