Redux介绍之Action

11 May

上一篇大致介绍了Redux的状态流程。其中Action出镜率很高,本篇就介绍一下Action。源码已上传Github,第二篇源代码请参照src/originReduxAction文件夹。

Action的本质是个描述已发生事件,能携带数据的plain object。作用是告知Reducer该更新Store里哪些state。而且根据Flux标准,需要是一个有type属性的plain object。典型的样子:

const ADD_TODO = 'ADD_TODO';

{
  type: 'ADD_TODO',
  payload: {
    text: 'Do something.'  
  }
}

{
  type: 'ADD_TODO',
  payload: new Error(),
  error: true
}

在Reducer里通过收到的Action的不同type值,去执行不同的修改state的行为。type属性通常会被定义成常量字符串或Symbol对象,而且常量字符串通常会被统一放在config文件中,便于管理。当然,这不是必须的,如果你的应用非常小,type属性直接赋值字符串也没问题,只要保证唯一就行。

通常来说同步Action设type就够了。异步Action,除了必须的type属性外,根据Flux标准,你还可以添加payload ,error,meta属性。

payload属性:顾名思义就是Action的额外的信息,可以设任意类型的值。通常当error属性为true时,payload会赋值error对象,例如rejected的promise信息。

error属性:当Action发生错误时,设为true。如果该属性为true以外的值,包括undefined或null,都认为Action没有错误。

meta属性:不适合放到payload里的信息,可以放到这个属性里,同样可以设任意类型的值。

除了上述4种属性,其实你还可以为Action对象添加任意属性,这完全由你自己决定。

现在我们将上一篇的例子代码,改造一下,目录结构如下,新建actions目录,将Action独立出来,新建configs目录存放Action的type值常量,最后将含DOM结构的源代码放入entries主目录:

Redux

actions/number.js:(这里补充一个小概念,Action是个plain object没错,但每次dispatch一个对象代码写起来麻烦。通常我们会如下创建个Action creator,即创建Action的函数。这样dispatch时,代码就能简化成store.dispatch(actions.incrementNum());

import * as constant from '../configs/action';

export const incrementNum = () => ({
    type: constant.INCREMENT,
});

export const decrementNum = () => ({
    type: constant.DECREMENT,
});

export const clearNum = () => ({
    type: constant.CLEAR_NUM,
});

configs/action.js:

export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
export const CLEAR_NUM = 'CLEAR_NUM';

entries/originReduxAction.js:

// 改前
addNum = () => {
    store.dispatch({ type: 'INCREMENT' });
};

minusNum = () => {
    store.dispatch({ type: 'DECREMENT' });
};

clearNum = () => {
    store.dispatch({ type: 'CLEAR_NUM' });
};

// 改后
addNum = () => {
    store.dispatch(actions.incrementNum());
};

minusNum = () => {
    store.dispatch(actions.decrementNum());
};

clearNum = () => {
    store.dispatch(actions.clearNum());
};

最终结果和第一篇是一样的,如下图数字会跟随点击的按钮发生变化。例子本身的结果不重要。重要的是代码的结构更加工程化,后几篇会继续完善代码结构。

Redux

最后重复一下Action的本质:是个描述已发生事件,能携带数据的plain object。使用Redux框架的话,你只能通过分派Action来修改state,不能直接修改Store里的state。这样代码更加可控,出了问题溯源起来更加方便。有关异步Action将在异步操作中介绍,但不管同步还是异步,Action的本质都是一样的。

Leave a Reply

Your email address will not be published. Required fields are marked *