action 普通JavaScript对象
--actioType.js定义行为类型
const GET_STUDENT_LIST = 'get_student_list'
store.js 存储数据state
--
reducer.js 接收state、action,并返回新state的函数
--子reducer.js
每个reducer函数负责独立管理state
--出口reducer.js
combineReducers({key:value})
组件中使用:sotre的state赋值给props
Redux 应用中数据的生命周期
- 调用 store.dispatch(action)
- Redux store 调用传入的 reducer 函数
- 根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树
- Redux store 保存了根 reducer 返回的完整 state 树
store 单一数据源
整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
维持应用的 state;
提供 getState() 方法获取 state;
提供 dispatch(action) 方法更新 state;
通过 subscribe(listener) 注册监听器;
通过 subscribe(listener) 返回的函数注销监听器。
通过 unsubscribe() 停止监听 state 更新
State 是只读的:唯一改变 state 的方法就是发起 action
store.dispatch({
type: 'COMPLETE_TODO',
index: 1
})
拆分数据处理逻辑时,你应该使用 reducer 组合 而不是创建多个 store
// createStore() 的第二个参数是可选的, 用于设置 state 初始状态。
let store = createStore(todoApp, window.STATE_FROM_SERVER)
action
Action 是把state数据从应用传到 store 的有效载荷。
一般来说你会通过 store.dispatch()
将 action 传到 store。
// 添加新 todo 任务的 action
const ADD_TODO = 'ADD_TODO'
// or
{
type: ADD_TODO, // action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。
text: 'Build my first Redux app' // action index 来表示用户完成任务的动作序列号
}
// 应用规模越来越大时,建议使用单独的模块或文件来存放 action
import { ADD_TODO } from '../actionTypes'
action 创建函数
// action 创建函数只是简单的返回一个 action
export function addTodo(text) {
return { type: ADD_TODO, text }
}
// ,Redux 中只需把 action 创建函数的结果传给 dispatch() 方法即可发起一次 dispatch 过程
dispatch(addTodo(text))
createAction
reducer
action 通过reducers改变 state tree :Reducer 只是一些纯函数,它接收先前的 state 和 action,并返回新的 state。
(previousState, action) => newState
谨记 reducer 一定要保持纯净。只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。
import { ADD_TODO, TOGGLE_TODO, VisibilityFilters } from './actions'
// Redux 首次执行时,state 为 undefined,此时我们可借机设置并返回应用的初始 state。const initialState = {
const initialState = {
visibilityFilter: VisibilityFilters.SHOW_ALL,
todos: []
};
// es6默认参数
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
// 不直接修改 state 中的字段,而是返回新对象
return Object.assign({}, state, {
visibilityFilter: action.filter
})
case ADD_TODO:
return···
default:
return state
}
}
export default handleActions(actions:{[actionType.]=(state,action)=>{return {new state}}},initialState)
- Redux 提供 combineReducers() 工具类来重构 todoApp
import { combineReducers } from 'redux'
const todoApp = combineReducers({
visibilityFilter,
todos
})
export default todoApp
container
Redux 的 React 绑定库是基于 容器组件和展示组件相分离 的开发思想
展示组件 | 容器组件 | |
---|---|---|
作用 | 描述如何展现(骨架、样式) | 描述如何运行(数据获取、状态更新) |
直接使用 Redux | 否 | 是 |
数据来源 | props | 监听 Redux state |
数据修改 | 从 props 调用回调函数 | 向 Redux 派发 actions |
调用方式 | 手动 | 通常由 React Redux 生成 |
- 使用 connect() 开发容器组件
使用 connect() 前,需要先定义 mapStateToProps 这个函数来指定如何把当前 Redux store state 映射到展示组件的 props 中
import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'
const mapStateToProps = (state, ownProps) => {
return {
active: ownProps.filter === state.visibilityFilter
}
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch(setVisibilityFilter(ownProps.filter))
}
}
}
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
export default VisibleTodoList