理解React中的Action:状态管理的核心概念

更新日期: 2025-10-11 阅读: 77 标签: React

react开发中,我们经常听到"Action"这个词。但Action并不是React自带的特性,而是来自状态管理工具如Redux、Flux、MobX,还有React内置的useReducer Hook。


什么是Action?

简单来说,Action就是描述应用中发生了什么事情。它告诉状态管理器:"嘿,这里有个事件发生了,你需要更新状态了"。

Action的核心思想:只说明发生了什么,不关心怎么更新状态。

它是用户意图的声明,比如"用户点击了按钮"或"数据加载完成",作为状态更新的触发信号。


为什么需要Action?

把状态更新写成Action形式有几个好处:

代码更清晰:Action明确表达了发生了什么事件,让代码容易理解
职责分离:组件只管触发Action,不管状态怎么更新。状态更新逻辑集中在Reducer里
方便调试:所有状态变化都由Action触发,可以清楚看到每个Action导致的状态变化
容易测试:生成Action的函数和更新状态的函数都很容易测试
支持中间件:明确的Action机制为添加额外功能提供了基础


Action在不同工具中的实现

Redux中的Action

Redux是最流行的状态管理库之一。

在Redux中:

Action是一个普通对象,必须有type属性

Action Creator是创建Action的函数

用dispatch函数来发送Action

示例代码:

// 定义Action类型
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

// 创建Action的函数
function increment() {
  return {
    type: INCREMENT
  };
}

function decrement(amount) {
  return {
    type: DECREMENT,
    payload: amount
  };
}

// 更新状态的函数
const initialState = { count: 0 };
function counterReducer(state = initialState, action) {
  switch (action.type) {
    case INCREMENT:
      return { ...state, count: state.count + 1 };
    case DECREMENT:
      return { ...state, count: state.count - action.payload };
    default:
      return state;
  }
}

// 在组件中使用
import React from 'react';
import { createStore } from 'redux';

const store = createStore(counterReducer);

function Counter() {
  const [count, setCount] = React.useState(store.getState().count);

  React.useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      setCount(store.getState().count);
    });
    return unsubscribe;
  }, []);

  const handleIncrement = () => {
    store.dispatch(increment());
  };

  const handleDecrement = () => {
    store.dispatch(decrement(5));
  };

  return (
    <div>
      <p>计数: {count}</p>
      <button onClick={handleIncrement}>增加</button>
      <button onClick={handleDecrement}>减少5</button>
    </div>
  );
}

useReducer中的Action

useReducer是React自带的Hook,用法和Redux很像。

import React, { useReducer } from 'react';

const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

const initialState = { count: 0 };
function counterReducer(state, action) {
  switch (action.type) {
    case INCREMENT:
      return { ...state, count: state.count + 1 };
    case DECREMENT:
      return { ...state, count: state.count - action.payload };
    default:
      return state;
  }
}

function CounterWithReducer() {
  const [state, dispatch] = useReducer(counterReducer, initialState);

  const handleIncrement = () => {
    dispatch({ type: INCREMENT });
  };

  const handleDecrement = () => {
    dispatch({ type: DECREMENT, payload: 5 });
  };

  return (
    <div>
      <p>计数: {state.count}</p>
      <button onClick={handleIncrement}>增加</button>
      <button onClick={handleDecrement}>减少5</button>
    </div>
  );
}

MobX中的Action

MobX是响应式状态管理库,用法不太一样。

import React from 'react';
import { makeObservable, observable, action } from 'mobx';
import { observer } from 'mobx-react';

class CounterStore {
  count = 0;

  constructor() {
    makeObservable(this, {
      count: observable,
      increment: action,
      decrement: action
    });
  }

  increment() {
    this.count++;
  }

  decrement(amount) {
    this.count -= amount;
  }
}

const counterStore = new CounterStore();

const MobxCounter = observer(() => {
  const handleIncrement = () => {
    counterStore.increment();
  };

  const handleDecrement = () => {
    counterStore.decrement(5);
  };

  return (
    <div>
      <p>计数: {counterStore.count}</p>
      <button onClick={handleIncrement}>增加</button>
      <button onClick={handleDecrement}>减少5</button>
    </div>
  );
});


处理异步操作

实际开发中经常需要处理异步操作,比如请求数据。

Redux中处理异步

Redux需要用中间件来处理异步,最常用的是redux-thunk。

// 安装:npm install redux-thunk

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

// 异步Action
export const fetchUsers = () => {
  return async (dispatch) => {
    dispatch({ type: 'FETCH_USERS_REQUEST' });
    
    try {
      const response = await fetch('/api/users');
      const users = await response.json();
      dispatch({ type: 'FETCH_USERS_SUCCESS', payload: users });
    } catch (error) {
      dispatch({ type: 'FETCH_USERS_FAILURE', payload: error.message });
    }
  };
};

// 在组件中
function UserList() {
  const dispatch = useDispatch();
  
  useEffect(() => {
    dispatch(fetchUsers());
  }, [dispatch]);
  
  // ... 组件其他代码
}

useReducer中处理异步

useReducer没有中间件,需要在组件内处理异步。

function DataLoader() {
  const [state, dispatch] = useReducer(dataReducer, initialState);
  
  useEffect(() => {
    const loadData = async () => {
      dispatch({ type: 'FETCH_START' });
      
      try {
        const response = await fetch('/api/data');
        const data = await response.json();
        dispatch({ type: 'FETCH_SUCCESS', payload: data });
      } catch (error) {
        dispatch({ type: 'FETCH_ERROR', payload: error.message });
      }
    };
    
    loadData();
  }, []);
  
  // ... 组件其他代码
}


Action的优缺点

优点:

状态变化可预测:知道什么Action会导致什么状态变化

方便调试:可以追踪每个状态变化

职责清晰:组件、Action、Reducer各司其职

容易测试:相关函数都是纯函数,测试简单

团队协作:统一的模式让团队合作更顺畅

缺点:

代码量多:即使是简单功能也要写很多代码

学习成本:需要理解很多新概念

小型项目过重:简单项目用useState就够了

异步处理复杂:需要额外配置


什么时候该用Action?

对于状态复杂、需要多人协作的大型项目,使用Action模式很有帮助。对于状态简单的小项目,直接用React的useState和useContext可能更合适。


总结

Action是React状态管理的核心概念,它把"发生了什么"和"状态怎么更新"分开,让代码更清晰、更易维护。虽然会增加一些代码量,但对于复杂应用来说,这些付出是值得的。

选择使用哪种状态管理方案时,要考虑项目规模、团队习惯和具体需求。理解Action的工作原理,能帮你做出更好的技术选型。

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!

链接: https://fly63.com/article/detial/12981

如何优雅的设计 React 组件

如今的 Web 前端已被 React、Vue 和 Angular 三分天下,尽管现在的 jQuery 已不再那么流行,但 jQuery 的设计思想还是非常值得致敬和学习的,特别是 jQuery 的插件化。

React深度编程:受控组件与非受控组件

受控组件与非受控组件在官网与国内网上的资料都不多,有些人觉得它可有可不有,也不在意。这恰恰显示React的威力,满足不同规模大小的工程需求。

React框架学习_关于React两种构建应用方式选择

一般在传统模式下,我们构建前端项目很简单。就是下载各种js文件,如JQuery、Echart等,直接放置在html静态文件。Webpack则是JavaScript中比较知名的打包工具。这两个构建工具构成了React应用快速搭建的基础。

Gatsby.js_一款基于React.js静态站点生成工具

Gatsby能快速的使用 React 生态系统来生成静态网站,可以结合React Component、Markdown 和服务端渲染来完成静态网站生成让他更强大。

React创建组件的三种方式及其区别

React推出后,出于不同的原因先后出现三种定义react组件的方式,殊途同归;具体的三种方式:函数式定义的无状态组件、es5原生方式React.createClass定义的组件、es6形式的extends React.Component定义的组件

react生命周期详解_深入理解React生命周期

React主要思想是通过构建可复用组件来构建用户界面,每个组件都有自己的生命周期,它规定了组件的状态和方法需要在哪个阶段改变和执行。所谓组件就是有限状态机,,表示有限个状态以及在这些状态之间的转移和动作行为的模型。

React + Webpack 构建打包优化

React 相关的优化:使用 babel-react-optimize 对 React 代码进行优化,检查没有使用的库,去除 import 引用,按需打包所用的类库,比如 lodash 、echarts 等.Webpack 构建打包存在的问题两个方面:构建速度慢,打包后的文件体积过大

react router中页面传值的三种方法

这篇文章主要介绍React Router定义路由之后如何传值,有关React和React Router 。react router中页面传值的三种方法:props.params、query、state

react 高阶组件的 理解和应用

react 高阶组件简单的理解是:一个包装了另一个基础组件的组件。高阶组件的两种形式:属性代理(Props Proxy)、反向继承 (Inheritance Inversion)

react中的refs属性的使用方法

React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!