例子:
https://codesandbox.io/s/react-hooks-demo-6-5iey8?file=/src/index.js
not magics just array
https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e
useState
let memoizedState = []; // hooks 存在這個數組
let cursor = 0; // 當前 memoizedState 下標
function useState(initialState) {
memoizedState[cursor] = memoizedState[cursor] || initialState;
const currentCursor = cursor;
function setState(newState) {
memoizedState[currentCursor] = newState;
render();
}
return [memoizedState[cursor++], setState]; // 返回當前 state 將 cursor + 1
}
function App() {
const [count, setCount] = useState(0);
const [username, setUsername] = useState("fan");
useEffect(() => {
console.log(count);
}, [count]);
useEffect(() => {
console.log(username);
}, [username]);
return (
<div>
<div>{count}</div>
<Button
onClick={() => {
setCount(count + 1);
}}
>
點擊
</Button>
<div>{username}</div>
<Button
onClick={() => {
setUsername(username + " hello");
}}
>
點擊
</Button>
</div>
);
}
const rootElement = document.getElementById("root");
function render() {
cursor = 0;
ReactDOM.render(<App />, rootElement);
}
render();
useEffect
function useEffect(callback, depArray) {
const hasNoDeps = !depArray;
const deps = memoizedState[cursor];
const hasChangeDeps = deps
? !depArray.every((el, i) => el === deps[i]) : true;
if(hasNoDeps || hasChangeDeps) {
callback();
memoizedState[cursor] = depArray;
}
// 為什么要 ++ , 這個位置 給 這個 state 使用了 要給下一個 state 一個 位置, 不要沖突了
cursor++;
}
let _deps;
function useEffect(callback, depArray) {
const hasNoDeps = !depArray;
// 新的數組的每一項是不是等于 之前數組的每一項 這對于比較 ['a', 1]這樣的基礎類型是 可以的, 但是比較引用類型呢
const hasChangeDeps = _deps
? !depArray.every((el, i) => el === _deps[i]) : true;
if(hasNoDeps || hasChangeDeps) {
callback();
_deps = depArray;
}
}