返回
深入剖析 React 函数组件 Hooks 之 useState
前端
2024-01-04 15:08:12
**一、useState 原理和源码**
useState 是 React 中用于管理状态的 Hook,它可以让函数组件具有状态管理的能力,就像类组件一样。useState 的工作原理是创建一个 state 对象,并在函数组件的每次重新渲染时,将这个 state 对象作为参数传递给它。
useState 的源码如下:
```javascript
import { unstable_now } from './scheduler';
export function useState(initialState) {
const hook = mountWorkInProgressHook();
// 获取更新时间
const timestamp = unstable_now();
const state = hook.memoizedState;
if (state !== null && state.time === timestamp) {
// 复用旧值
hook.memoizedState = state.next;
return [state.value, updateState];
}
// 首次渲染或者强制更新
hook.memoizedState = {
value: typeof initialState === 'function' ? initialState() : initialState,
time: timestamp,
next: null,
};
return [hook.memoizedState.value, updateState];
function updateState(newValue) {
// 创建一个新的 state 对象
const nextState = {
value: typeof newValue === 'function' ? newValue(hook.memoizedState.value) : newValue,
time: unstable_now(),
next: null,
};
// 将新的 state 对象链接到当前 state 对象的后面
hook.memoizedState = hook.memoizedState.next = nextState;
// 请求重新渲染
scheduleWork(Component, timestamp);
}
}
二、useState 的使用场景和最佳实践
useState Hook 的使用场景非常广泛,它可以用于管理各种各样的状态,例如:
- 表单输入框中的值
- 组件的可见性
- 组件的数据
- 组件的样式
useState Hook 的最佳实践包括:
- 尽量将状态保存在函数组件的内部,避免将其暴露给外部。
- 避免在函数组件的每次渲染中都更新状态,只在必要时才更新状态。
- 尽量使用 reducer 来管理复杂的状态。
三、useState 的案例演示
下面是一个使用 useState Hook 来管理表单输入框值的案例:
import React, { useState } from 'react';
function App() {
const [inputValue, setInputValue] = useState('');
const handleChange = (event) => {
setInputValue(event.target.value);
};
return (
<div>
<input type="text" value={inputValue} onChange={handleChange} />
<p>输入的值:{inputValue}</p>
</div>
);
}
export default App;
在这个案例中,我们使用 useState Hook 来管理表单输入框的值。当用户输入值时, handleChange 函数会被调用,并调用 setInputValue 函数来更新表单输入框的值。
四、总结
useState Hook 是 React 中用于管理状态的 Hook,它可以让函数组件具有状态管理的能力,就像类组件一样。useState Hook 的工作原理是创建一个 state 对象,并在函数组件的每次重新渲染时,将这个 state 对象作为参数传递给它。
useState Hook 的使用场景非常广泛,它可以用于管理各种各样的状态。useState Hook 的最佳实践包括:尽量将状态保存在函数组件的内部,避免将其暴露给外部;避免在函数组件的每次渲染中都更新状态,只在必要时才更新状态;尽量使用 reducer 来管理复杂的状态。