useState
认识 useState
- useState 通过一个状态变量来管理组件状态,在状态发生变化时能够自动重新渲染组件
- useState 接收唯一一个参数,在组件第一次被调用时用来初始化值 。如果是个函数,执行函数并取返回值;如果不是函数,直接赋值
- useState 的返回值是一个数组,可以通过数组的解构,方便调用
- useState 可以多次调用,每次调用 useState 都会创建一个新的 state 对象和对应的 setState 函数,这样能够管理组件中多个状态
使用方法
const [counter, setCounter] = useState(0)
const [name, setName] = useState(() => {
// 先执行一定的逻辑,后再返回初始值
const initialState = getFullName();
return initialState;
}); // 参数是 Function
useState 的实现原理
React 会将 state 对象和 setState 函数保存在“hook”对象中,每个组件都有自己独立的 hook 对象,用来存储组件的状态和更新函数。当调用 useState()时,会先检查当前组件是否已经有对应的 state,如果有就返回已有的 state,否则就创建一个新的 state,并返回它
实现一个简单的 useState
function app() {
// const [num, setNum] = gyUseState(1);
const [num, setNum] = gyUseState(() => 100);
console.log(num);
return {
setNum,
};
}
// 全局对象fiber来保存上一次的状态
let fiber = {};
// 区分是否调用过
let hasCalled = false;
function dispatch(pending, action) {
pending.action = action;
}
function gyUseState(initState) {
if (typeof initState === "function") {
initState = initState();
}
// 还没有执行过函数
if (!hasCalled) {
// 创建一个对象
const hook = {
basicState: initState,
pending: {
action: null,
},
};
// 挂载到fiber上
fiber.hook = hook;
// 标记已经执行过
hasCalled = true;
return [hook.basicState, dispatch.bind(null, fiber.hook.pending)];
} else {
fiber.hook.basicState =
typeof fiber.hook.pending.action === "function"
? fiber.hook.pending.action(fiber.hook.basicState)
: fiber.hook.pending.action;
// 返回数组
return [fiber.hook.basicState, dispatch.bind(null, fiber.hook.pending)];
}
}
const myApp = app(); // 100
// myApp.setNum(10)
// app()
myApp.setNum((num) => num + 1);
app(); // 101