1. React状态管理入门:什么是状态管理、为什么需要状态管理、React中的状态与props的区别

好,咱们开始第一课。

说实话,我见过不少新手一上来就扎进 Redux、Zustand 这些库,结果学了半天还是懵的。为什么?因为连最基础的问题都没搞明白——状态管理到底是什么?

这一章,咱们就把地基打牢。不扯虚的,直接上干货。

1.1 什么是状态管理

先问个问题:你写 React 组件的时候,那些会变的数据,比如用户输入、接口返回、开关状态……它们都放哪了?

嗯,答案就是——状态(State)

状态管理,说白了就是一套组织、更新、共享这些数据的方法论

核心定义:状态管理 = 数据 + 数据的变化逻辑 + 数据在组件间的流动方式。

举个例子。你写一个计数器:

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

这里的 count 是状态,setCount 是更新逻辑,组件重新渲染是数据流动的结果。这其实就是最基础的状态管理。

我个人习惯把状态管理分成三个层次:

  • 组件内部状态:用 useState 搞定,自己管自己。
  • 跨组件状态:需要提升到父组件,或者用 Context。
  • 全局状态:多个不相关的组件都要用,这时候才需要 Redux 这类工具。

我在项目中遇到过不少团队,一上来就用 Redux 管理所有状态,连个输入框的值都要走全局 store。结果代码又臭又长,维护起来想哭。记住:能用局部状态解决的问题,别往全局塞

1.2 为什么需要状态管理

你可能会想:我用 useState 不也能写项目吗?为什么还要学状态管理?

好问题。咱们来看一个真实场景。

假设你做一个购物车页面:

  • 商品列表组件要显示数量
  • 购物车图标要显示总件数
  • 结算组件要计算总价
  • 用户登录后还要同步购物车数据

如果只用 useState,你会怎么做?

嗯,大概率是:把状态放在最顶层的 App 组件,然后一层层用 props 往下传。组件多了,你就得经历「props 层层传递」的痛苦——明明中间组件不需要这个数据,却要帮忙传一手。这就是所谓的「prop drilling」

我曾经接手过一个项目,一个状态从顶层传到第 7 层子组件,中间 5 个组件纯粹是「传话筒」。改一个字段,要改 6 个文件。那感觉,就像在玩「传话游戏」,最后传出来的东西对不对全靠运气。

所以,为什么需要状态管理?说白了就三点:

  1. 避免 prop drilling:让数据直达需要的组件,中间组件不用当「二传手」。
  2. 统一数据源:同一个数据只有一个来源,不会出现「A 组件改了数据,B 组件不知道」的情况。
  3. 可预测的数据流:数据怎么来、怎么变、变到哪里去,一目了然。调试起来也方便。

你想想看,一个项目如果数据流是混乱的,Bug 就会像野草一样,割了一茬又长一茬。状态管理就是给你一把「除草机」。

1.3 React中的状态与props的区别

这个点,我每次面试新人都会问。能讲清楚的人,React 基础基本没问题。

咱们直接上对比表:

对比维度 State(状态) Props(属性)
数据来源 组件内部自己管理 父组件传递过来
可变性 可变(通过 setState) 不可变(只读)
谁可以修改 组件自身 父组件(通过回调)
用途 存储动态数据 配置组件、传递数据
触发渲染 setState 会触发重新渲染 父组件重新渲染时,子组件跟着渲染

光看表可能有点抽象。咱们写个例子:

// 父组件
function Parent() {
  const [name, setName] = useState('张三'); // 这是 state

  return (
    <div>
      <Child name={name} />  {/* 把 state 作为 props 传给子组件 */}
      <button onClick={() => setName('李四')}>改名</button>
    </div>
  );
}

// 子组件
function Child(props) {
  // props.name 是只读的,不能直接修改
  return <p>我的名字是:{props.name}</p>;
}

这里有几个关键点:

  • nameParent 组件的 state,它自己管自己。
  • Child 组件通过 props.name 拿到数据,但不能直接改。
  • 如果 Child 想改名字,只能通过父组件传一个回调函数下去。

小技巧:我判断一个数据该用 state 还是 props,就一句话——「这个数据会变吗?如果会变,是谁让它变的?」。如果是组件自己让它变,用 state;如果是别人传进来的,用 props。

嗯,这里要注意一个常见的坑:不要直接修改 props。我见过有人这么写:

// ❌ 错误写法
function Child(props) {
  props.name = '王五'; // 直接修改 props!React 会警告
  return <p>{props.name}</p>;
}

为什么不行?因为 props 是只读的。你改了父组件也不知道,数据就乱套了。正确的做法是:

// ✅ 正确写法
function Child(props) {
  const [localName, setLocalName] = useState(props.name); // 如果需要修改,复制一份到本地 state
  return <p>{localName}</p>;
}

说白了,state 和 props 的关系就像「家产」和「礼物」:state 是你自己挣的钱,想怎么花都行;props 是别人送你的东西,你可以用,但不能随便改。想改?得先跟送礼的人商量(调用父组件的回调)。

这一章的内容就到这里。记住:状态管理不是银弹,但理解它的本质,能让你在 React 的世界里走得更远。下一章,咱们聊聊 React 自带的 useStateuseReducer,看看它们到底怎么用才顺手。