React Redux 备忘录

Redux 中文文档

传送门

代码结构

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

给Action加点特效

普通的Action

暂且称它为pureAction,够纯净

1
2
3
4
5
6
7
export function Foo(valueA,valueB,valueC) {
...
return {
type: SOME_NAME,
payload: values
}
}

普通的Action的缺陷

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

使用redux-thunk

redux-thunk其实是redux的一个middleware

使用方法

1
npm install --save redux-thunk
1
2
3
4
5
6
7
8
9
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用于判断和计算

1
2
3
4
5
6
7
8
9
10
11
export function Foo() {
return (dispatch, getState) => {
const { stateA } = getState()

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

dispatch(pureAction())
}
}

Action内异步请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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中的简单使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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