Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

听说你需要这样了解 Redux(三) #26

Open
rccoder opened this issue Mar 28, 2017 · 0 comments
Open

听说你需要这样了解 Redux(三) #26

rccoder opened this issue Mar 28, 2017 · 0 comments

Comments

@rccoder
Copy link
Owner

rccoder commented Mar 28, 2017

Redux 异步

随着场景的复杂化,在异步结果得到之后再进行 dispatch 变得越来越不可取与不可维护。Redux 自身并没打算解决这个问题,但由于提供了 middleware,可以在这层上做文章。

比较熟知的 Redux 异步 middleware 有 redux-thunk, redux-promise, redux-saga 等。

关于这些 middlware 如何使用,可以参考我近期校对过的文章 Redux 异步四兄弟,如果怀疑文章翻译的准确度,可以直接看原文 Redux 4 ways

标准化的 action

Redux 自身没有要求 action 应该是什么格式,但按照一些实践,我们知道 action 一般包含 type 和 payload。

那如何更好的去写出标准化的 action 呢?可以看 redux-actions

如果不想仔细看 redux-actions 相关介绍,可以简单看一下我下面的介绍:

团队开发中的标准化 action

如果在多人开发中,不对 action 的设计做一定的规范,就可能会出现多种不同形式的 action,比如:

type:...|text:...

{
  type: ...,
  data: ...,
}

{
  actionType: ...,
  data: ...,
}

{
  type: ...,
  payload: ...,
}

那如何去设计一个大家可以都接受的 action 呢,在action 进化的历程中,Flux Standard Action 的设计受到广为推崇。

它约定一个 action 必须是一个对象,并且至少包含一个 key 为 type 的属性表示 action 类型。除此之外,还可以有 payload 属性表示 action 携带的数据,error 属性表示 action 是否是 “错误的”,meta 属性表示其他一些信息,当然,这只是可选的。

redux-actions 封装了一个 createAction 的函数,用它我们就能写出更加简约的 action creator,并且符合 Flux Standard Action 的标准。

以外我们写 action creator 的时候是这样:

import * as types from '../constant';

export function fetchingLogin() {
  return {
    type: types.FETCHING_LOGIN_SUCCESS,
  }
}

export function fetchingLoginSuccess(payload) {
  return {
    type: types.FETCHING_LOGIN_SUCCESS,
    payload,
  }
}

export function fetchingLoginFailure(payload) {
  return {
    type: types.FETCHING_LOGIN_FAILURE,
    payload,
    error: true,
  }
}

利用 redux-actions,我们只需要这样做:

import { createAction } from "redux-actions";
import * as types from '../constant';

export const fetchingLogin = createAction(types.FETCHING_LOGIN);
export const fetchingLoginSuccess = createAction(types.FETCHING_LOGIN_SUCCESS, data => data);
export const fetchingLoginFailure = createAction(types.FETCHING_LOGIN_FAILURE, data => data);

这样就能创建出一个非常标准化的 action 了。

同样,我们在 reducer 中依旧可以:

import * as actions from '../action';

const initState = {
  status: true,
}

export default function isLoginReducer(state = initState, action) {
  switch(action.type) {
    case actions.CHANGE_IS_LOGIN: {
      return {
        ...state,
        status: action.payload,
      }
    }
    default: {
      return state;
    }
  }
}

当然,redux-actions 提供了更简洁的 API handleActions 可以写出更加简约的 renducer:

import { handleActions } from 'redux-actions';

import * as actions from '../action';

const initState = {
  status: true,
}

const isLoginReducer = handleActions({
  [actions.changeIsLogin]: (state, action) => ({
    ...state,
    status: action.payload
  }),
}, initState);

export default isLoginReducer;

这样,教会和你合作的同学使用 redux-actions,就能写出风格一致的 action。

再也不会盯着乱七八糟的 action 喊出 WTF!

听说这是最佳实践

业界关于 redux 的实践风格已经是保持基本一致了,也就是说按照上面 Redux 4 ways 创建出了风格基本可以解决大部分的问题。

值得注意是关于 React 组件方向最好保持纯 React 组件,保持和 Redux 之间不存在耦合。和 Redux 相关的 dispatch 可以放在 container 组件中,通过在 connect 中 mapDispatchToProps 传给 container,然后调用相应的函数即可:

import { changeIsLogin } from '../../action';

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    changeIsLogin: (status) => {
      dispatch(changeIsLogin(status));
    }
  }
}


this.props.changeIsLogin(!this.props.isLogin.status)

系列文章

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant