React Redux 备忘录

Posted by Michael on 2016-08-25

Redux 中文文档

传送门

代码结构

个人推荐ducks-modular-redux的构建方式,把actionTypes, actions, reducer放在同一个文件中,而不是各自分开算落在项目的各处。

给Action加点特效

普通的Action

暂且称它为pureAction,够纯净

export function Foo(valueA,valueB,valueC) {
  ...
  return {
    type: SOME_NAME,
    payload: values
  }
}

普通的Action的缺陷

  1. Action内部无法感知State用于判断和计算
  2. 如何支持单个或者多个有顺序的异步操作?

使用redux-thunk

redux-thunk其实是redux的一个middleware

使用方法

npm install --save redux-thunk
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';

// Note: this API requires redux@>=3.1.0
const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

更多可以参考http://cn.redux.js.org/docs/advanced/AsyncActions.html

Action内感知State用于判断和计算

export function Foo() {
  return (dispatch, getState) => {
    const { stateA } = getState()

    if (stateA % 2 === 0) {
      return
    }

    dispatch(pureAction())
  }
}

Action内异步请求

export function fetchPosts(subreddit) {

  // Thunk middleware 知道如何处理函数。
  // 这里把 dispatch 方法通过参数的形式传给函数,
  // 以此来让它自己也能 dispatch action。

  return function (dispatch) {

    // 首次 dispatch:更新应用的 state 来通知
    // API 请求发起了。

    dispatch(requestPosts(subreddit))

    // thunk middleware 调用的函数可以有返回值,
    // 它会被当作 dispatch 方法的返回值传递。

    // 这个案例中,我们返回一个等待处理的 promise。
    // 这并不是 redux middleware 所必须的,但这对于我们而言很方便。

    return fetch(`http://www.subreddit.com/r/${subreddit}.json`)
      .then(response => response.json())
      .then(json =>

        // 可以多次 dispatch!
        // 这里,使用 API 请求结果来更新应用的 state。

        dispatch(receivePosts(subreddit, json))
      )

      // 在实际应用中,还需要
      // 捕获网络请求的异常。
  }
}

Component中的简单使用

import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'

const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_ALL':
      return todos
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
  }
}

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

export default VisibleTodoList

推荐文章:React和Redux的连接react-redux