使用场景
- useState:适用于管理简单的状态,例如单个布尔值、数字或字符串。这种状态通常不依赖于之前的状态,并且状态更新逻辑较为简单。
- useReducer:适用于管理复杂的状态,尤其是当状态更新依赖于之前的状态,或者有多个不同类型的更新逻辑时。它类似于 Redux 的 reducer 概念,使得状态管理更具可预测性和维护性。
更新逻辑
- useState:通过调用 setState 函数来更新状态,新状态可以是一个值或一个函数(当新状态依赖于之前的状态时)。每次调用 setState 会直接替换之前的状态。
- useReducer:通过 dispatch 一个 action 来更新状态,reducer 函数根据接收到的 action 类型和当前状态计算出新的状态。这种方式使得状态更新逻辑更加集中和清晰,便于追踪和调试。
性能
- useState:每次状态更新都会触发组件重新渲染,即使新状态与旧状态相同(除非使用 React.memo 进行优化)。
- useReducer:如果在 reducer 中实现了合理的状态比较逻辑,通过 shouldComponentUpdate 或 React.memo 可以避免不必要的重新渲染。因为 dispatch 相同 action 时,如果状态没有变化,reducer 可以返回相同的状态,从而避免不必要的更新。
示例
useState 示例
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
};
export default Counter;
useReducer 示例
import React, { useReducer } from 'react';
const initialState = {
count: 0
};
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
case 'DECREMENT':
return { ...state, count: state.count - 1 };
default:
return state;
}
};
const Counter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const increment = () => {
dispatch({ type: 'INCREMENT' });
};
const decrement = () => {
dispatch({ type: 'DECREMENT' });
};
return (
<div>
<p>Count: {state.count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
};
export default Counter;