Last updated on
React Hooks 和 Effect handle function
Hooks 的顺序
下面的代码模拟了 hooks 的基本机制,可以参考回答一些 hooks 的问题
import { useEffect } from "react";
import ReactDOM from "react-dom/client";
const state = [];
const setters = [];
let firstRun = true;
let cursor = 0;
function createSetter(cursor) {
return function setterWithCursor(newVal) {
state[cursor] = newVal;
render();
};
}
export function useState(initVal) {
if (firstRun) {
state.push(initVal);
setters.push(createSetter(cursor));
}
const setter = setters[cursor];
const value = state[cursor];
cursor++;
return [value, setter];
}
function MyComponent() {
const [firstName, setFirstName] = useState("Rudi"); // cursor: 0
const [lastName, setLastName] = useState("Yardley"); // cursor: 1
return (
<div>
<button onClick={() => setFirstName(`${firstName}-Richard`)}>
{firstName}
</button>
<button onClick={() => setLastName(`${lastName}-Fred`)}>
{lastName}
</button>
</div>
);
}
export function CustomUseStateDemo() {
cursor = 0;
console.log("state before render", JSON.parse(JSON.stringify(state)));
const result = MyComponent();
firstRun = false;
console.log("state after render", JSON.parse(JSON.stringify(state)));
return result;
}
let lastRoot;
const render = (root?) => {
if (!root) {
root = lastRoot;
}
lastRoot = root;
root.render(<CustomUseStateDemo />);
};
export function Demo() {
useEffect(() => {
const root = ReactDOM.createRoot(document.getElementById("state"));
render(root);
}, []);
return <div id="state"></div>;
}

演示可见 链接

useLayoutEffect 和 useEffect
