React 函数式组件是没有状态的,需要 Hooks 进行状态的存储,那么状态是怎么存储的呢?Hooks是保存在 Fiber 树上的,多个状态是通过链表保存,本文将通过源代码分析 Hooks 的存储位置。
创建组件
首先我们在组件中添加两个 state,counterState 和 infoState
import logo from './logo.svg';
import './App.css';
import { useState } from 'react';
function App() {
const [counter, setCounter] = useState(10)
const [info, infoState] = useState(20)
const handleInputChange = (event) => {
setCounter(event.target.value);
};
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload. {counter} {info}
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<input onChange={handleInputChange}></input>
</header>
</div>
);
}
export default App;
useState 绑定过程
在 useState 加断点进入代码, 可以看到代码调用dispacher.useState:
dispatcher.useState 初始化状态
绑定WIP hooks
初始化 hooks 链表,代码中有两个 State,所以会调用两次,
useState 更新
更新数据,启动页面更新渲染
进入 Hook 更新方法
进入updateReducer
获取当前 hook
Hooks Queue中保存着需要更新的数据
更新状态
总结
useState 初始化时,会创建 hooks 链表,并保存到 FilberNode 的memoizedState
属性上,更新时,从 FiberNode 上获取hooks并检查是否有带待处理的更新。