其实这不是本身第一次看到redux吧,只是以前瞧见的时候,感受不太好理解它想要表达的意思。后来寒假的时候作APP用到了mobX,一样是状态管理,可是我以为mobX的语法很是容易理解。也是由于用了mobX反过头来瞧瞧redux,就发现有那么一点思路了,不过这篇文章可能有点乱~有的是直接来自官方文档的,若是有不对的地方,欢迎指出。html
引用自官网的介绍:react
redux是JavaScript状态容器,提供可预测化的状态管理。
说简单了就是相似于一个临时的状态记录和管理工具,当页面上发生了一些交互动做会把页面呈现的数据内容进行修改它就要出场了。这其中有几个重要的角色,分别是Store、Action、以及Reducer。redux
一个Redux应用只有一个store,相似因而咱们应用中全部的数据状态集合,也意味着全部的数据都遵循相同的生命周期,好处是方便了调试、撤销/重作、注入客户端等一系列操做。
Redux store保存了根reducer返回的完整state树,新树则是下一个state。state是只读的,监听器里能够调用store.getState()得到当前state。全部订阅 store.subscribe(listener)的监听器都将被调用。
在根文件输出的时候,能够用一个Provider标签包裹,把store加入Provider的属性,能够作到下面使用connect()的组件都能共享store的内容。并发
建立过程dom
import { createStore } from 'redux' import { Provider } from 'react-redux' import todoApp from './reducers' //引入根Reducer let store = createStore(todoApp) //第二个参数可选, 用于设置 state 初始状态。 render( (<Provider store={store}> <App /> </Provider>), document.getElementById('root') )
故名思意,action为一个动做,描述发生了什么事。官方解释是:数据从应用传到 store 的有效载荷。action本质是一个普通对象,必需要有type属性来标识每个不一样的动做。ide
{ type: ADD_TODO, text: 'go shopping' }
以上能够理解为XX的任务列表添加了购物这个活动。
尽可能减小在 action 中传递的数据。
通常是经过store.dispatch()将action传到store。函数
因为action可能会有不少不少个,好比一样是添加一个待办项,可是里面传输的文字并不同,因此每次都要从新闯进一个新的action。可是使用函数,就不用这么麻烦了,这样的函数就是action建立函数。工具
function addTodo(text) { return { type: ADD_TODO, text } }
把 action 建立函数的结果传给 dispatch() 方法便可把数据传向store:spa
dispatch(addTodo(text))
或建立一个被绑定的action建立函数来自动 dispatch,而后再调用这个函数:调试
const boundAddTodo = text => dispatch(addTodo(text))
Reducers本质是纯函数,用于指定状态的变化如何响应actions并发送到store,因此它接收旧的state和action,根据action的type和其余内容来返回新的state。根Reducer(也就是总的)能够被划分为不少个小的reducer来对应不一样的处理。
function todoApp(state = initialState, action) { case(action.type){ //处理省略,最后返回新的state } }
注意:
在Reducer内禁止进行如下操做:
根reducer结构能够用combineReducers()拆成多个函数:
let todoApp = combineReducers({ todos, visibleTodoFilter })
以上todos和visibleTodiFilter分别是两个reducer,当触发action后。这个函数会调用这两个reducer,而且把两个结果并成一个state树。
在React项目中使用Redux,有两种组件,分为容器组件和展现组件。容器组件用域数据获取和状态更新,是直接使用Redux,监听Redux的state,同时向Redux派发actions。而展现组件是是从容器组件传来的数据,调用props来获取。在项目开发的时候,最好放在不一样的文件夹里来写。
源码地址:http://www.redux.org.cn/docs/...
index.js
import React from 'react' import { render } from 'react-dom' import { Provider } from 'react-redux' import { createStore } from 'redux' import todoApp from './reducers' //引入根Reducer import App from './components/App' //引入主组件 let store = createStore(todoApp) render( //使用Provider包裹主组件,为了能使用connect共享state <Provider store={store}> <App /> </Provider>, document.getElementById('root') )
actions/index.js
let nextTodoId = 0 //建立于添加待作事项目的action export const addTodo = text => { return { type: 'ADD_TODO', id: nextTodoId++, text } } //建立过滤筛选动做的action export const setVisibilityFilter = filter => { return { type: 'SET_VISIBILITY_FILTER', filter } } //建立完成/取消完成动做相关的action export const toggleTodo = id => { return { type: 'TOGGLE_TODO', id } }
reducers/todos.js
与待办事列表处理相关的reducer:
const todos = (state = [], action) => { switch (action.type) { //若是是添加待办事,则与原有待办项目合并 case 'ADD_TODO': return [ ...state, { id: action.id, text: action.text, completed: false } ] //如果完成/取消完成某事,则建立副本进行状态修改 case 'TOGGLE_TODO': return state.map(todo => (todo.id === action.id) ? {...todo, completed: !todo.completed} : todo ) default: return state } } export default todos
reducers/visibilityFilter.js
与筛选过滤有关的reducer:
const visibilityFilter = (state = 'SHOW_ALL', action) => { switch (action.type) { //若是是设置筛选,返回action对象的filter属性 case 'SET_VISIBILITY_FILTER': return action.filter default: return state } } export default visibilityFilter
reducers/index.js
import { combineReducers } from 'redux' import todos from './todos' import visibilityFilter from './visibilityFilter' //根reducer分为todos和visibilityFilter两个子reducer const todoApp = combineReducers({ todos, visibilityFilter }) export default todoApp
containers/VisibleTodoList.js
import { connect } from 'react-redux' import { toggleTodo } from '../actions' import TodoList from '../components/TodoList' const getVisibleTodos = (todos, filter) => { switch (filter) { case 'SHOW_COMPLETED': return todos.filter(t => t.completed) case 'SHOW_ACTIVE': return todos.filter(t => !t.completed) case 'SHOW_ALL': default: return todos } } //只要store改变,mapStateToProps 函数就会被调用。该回调函数返回一个纯对象,会与组件的 props 合并 const mapStateToProps = state => { return { todos: getVisibleTodos(state.todos, state.visibilityFilter) } } //若是传递的是一对象,那么每一个定义在该对象的函数都将被看成 Redux action creator,对象所定义的方法名将做为属性名;每一个方法将返回一个新的函数,函数中dispatch方法会将action creator的返回值做为参数执行。这些属性会被合并到组件的 props 中。 const mapDispatchToProps = dispatch => { return { onTodoClick: id => { dispatch(toggleTodo(id)) } } } //链接获取store数据,返回一个新的已与 Redux store 链接的组件类 const VisibleTodoList = connect( mapStateToProps, mapDispatchToProps )(TodoList) export default VisibleTodoList