Day 8:状态管理原理

6 阅读2分钟

Day 8:状态管理原理

核心概念

状态管理 = React 的"大管家",帮你管好数据

不用状态管理用状态管理
数据散得到处都是集中在一个地方
传递 props 麻烦随时随地都能用
很难追踪数据变化一切都可追溯

常见状态管理方案

  1. useState - 组件内部状态,最简单
  2. Context - 跨组件共享,有性能问题
  3. Redux - 功能最全,代码多
  4. Zustand - 轻量简单,面试加分

useState

function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

Context

// 创建
const ThemeContext = React.createContext('light');

// 生产者
<ThemeContext.Provider value="dark">
  <Toolbar />
</ThemeContext.Provider>

// 消费者
function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div>{theme}</div>;
}

Redux

核心流程

Action → Dispatch → Reducer → State → View

代码示例

// 定义 Reducer
const counterReducer = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT': return state + 1;
    case 'DECREMENT': return state - 1;
    default: return state;
  }
};

// 创建 Store
const store = createStore(counterReducer);

// 派发
store.dispatch({ type: 'INCREMENT' });

// 获取
store.getState();

createStore 简化实现

function createStore(reducer) {
  let state;
  let listeners = [];
  
  const getState = () => state;
  
  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };
  
  const subscribe = (listener) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(l => l !== listener);
    };
  };
  
  dispatch({ type: '@@INIT' });
  
  return { getState, dispatch, subscribe };
}

Zustand

import { create } from 'zustand';

const useStore = create(set => ({
  count: 0,
  increase: () => set(state => ({ count: state.count + 1 })),
}));

// 使用(无需 Provider!)
function Counter() {
  const { count, increase } = useStore();
  return <button onClick={increase}>{count}</button>;
}

Zustand vs Redux:

特性ReduxZustand
代码量极少
配置需要创建 store、reducer、action一行代码
Provider需要不需要

面试高频问题

问题答案要点
React 状态管理有哪些方式?useState, Context, Redux, Zustand
Redux 核心概念?Store, Action, Reducer, Dispatch
Redux 为什么要用不可变数据?方便追踪变化、便于 time-travel
Context 的缺点?会导致所有消费者重渲染
Redux vs Zustand?Redux 完整但繁琐,Zustand 轻量
如何优化 Context 性能?拆分 Context,按需订阅

自测答案

1. Redux 的核心工作流程是什么?

Action → Dispatch → Reducer → New State → Subscribe → View

1. 组件派发 action(描述要做什么)
2. Redux 调用 reducer 计算新状态
3. 更新 store 中的 state
4. 通知所有订阅者
5. 组件重新渲染

2. 为什么 Redux 需要不可变数据?

  • 变化追踪:用 === 就能判断是否变化(O(1)),不用深比较
  • 时间旅行:记录所有 state 历史,可回滚调试
  • 性能优化:shouldComponentUpdate 更好用

3. Context 的性能问题及解决方案?

  • 问题:Provider value 变化时,所有消费者都会重渲染
  • 解决方案
    1. 拆分成多个小 Context
    2. memo 包裹消费组件
    3. useMemo 保持 value 稳定

4. Zustand 相比 Redux 的优势?

  • 代码量极少,一行代码创建 store
  • 无需 Provider,直接用 hook
  • 无需 action creator,函数直接更新
  • 组件可以只订阅需要的字段