用过react的人都知道,项目中最经常使用的hooks有 useState,useEffect等,今天就来学习一下使用方式,并非简单实现一下。代码见这里。
- useState:状态
useState使用方法:
let [state, setState] = React.useState(initialState);
返回一个 state,以及更新 state 的函数。
在初始渲染期间,返回的状态 (state) 与传入的第一个参数 (initialState) 值相同。
实现方式:
let stateHooks;
let stateHookIndex;
function useState(initial) {
//
let currentFiber = wipFiber;
const oldHook = currentFiber.alternate?.stateHooks[stateHookIndex];
const stateHook = {
state: oldHook ? oldHook.state : initial,
queue: oldHook ? oldHook.queue : [],
};
// 调用
stateHook.queue.forEach((action) => {
stateHook.state = action(stateHook.state);
});
stateHook.queue = [];
stateHookIndex++;
stateHooks.push(stateHook);
currentFiber.stateHooks = stateHooks;
function setState(action) {
// stateHook.state = action(stateHook.state);
const eagerState =
typeof action === "function" ? action(stateHook.state) : action;
if (eagerState == stateHook.state) return;
stateHook.queue.push(typeof action === "function" ? action : () => action);
wipRoot = {
...currentFiber,
alternate: currentFiber,
};
nextWorkOfUnit = wipRoot;
}
return [stateHook.state, setState];
}
- useEffect:副作用,代替生命周期
该 Hook 接收一个包含命令式、且可能有副作用代码的函数。 使用方式:
React.useEffect(()=>{
// todo
},[]);
在函数组件主体内(这里指在 React 渲染阶段)改变 DOM、添加订阅、设置定时器、记录日志以及执行其他包含副作用的操作都是不被允许的,因为这可能会产生莫名其妙的 bug 并破坏 UI 的一致性。
使用 useEffect 完成副作用操作。赋值给 useEffect 的函数会在组件渲染到屏幕之后延迟执行。
默认情况下,effect 将在每轮渲染结束后执行,但你可以选择让它在只有某些值改变的时候才执行。
实现代码:
// 调用时机?在react完成对 dom 的渲染之后,并且浏览器完成绘制之前
let effectHooks;
function useEffect(callback, deps) {
const effectHook = {
callback,
deps,
cleanup: undefined,
};
effectHooks.push(effectHook);
wipFiber.effectHooks = effectHooks;
}
不是每次改变都去更新,而是一次性收集起来,统一进行更新,这也是优化点之一,不需要频繁的变动。
- useCallback: 性能优化
待完成
不是结束,是新的开始,未来走的每一步。