Redux之深入理解Store、Action、Reducer
前面有一篇文章比较详细的介绍了redux,那么这篇文章主要是对redux中的几个角色进行深入的理解。主要有以下几个部分:
- store
- action
- reducer
- combineReducers
- bindActionCreators
理解Store
const store = createStore(reducer)
store中常用的三个方法:
- getState()-获取state对象
- dispatch(action)-当从UI上改变某个状态的时候,需要dispatch一个action
- subscribe(listener)-通知UI,做出对应的改变
理解Action
一个Action其实是描述行为的数据结构,如一个ToDoList的应用结构。比如要增加一个ToDoItem,用action去描述:
{ type:'ADD_TODO', text:'Build my first Redux App' }
理解Reducer
那么怎么去更新之前的ToDoList,这时候就需要reduer,reducer其实是一个纯函数(其输出结果只依赖于传入的参数)。这个函数一般接受两个参数:
- state-之前的状态
action
function todoApp(state=initialState,action){ switch(action.type){ case ADD_TODO: return Object.assign({},state,{ todos:[ ...state.todos, { text:action.text, completed:false } ] }) break; default: return state } }
理解combineReducers
我们知道一个reducer其实就是一个函数,如果你的应用中有多个reducer的话,那么如何将它们组合起来一起使用?这时候就需要combineReducers这个工具函数了。这个函数可以接受多个reducer作为参数,最终形成的是一个封装后的函数。这个封装后的函数其实也是一个reducer.
import {combineReducers} from 'redux' import todoApp from './todoApp' import counter from './counter' export default combineReducers({ todoApp, counter })
理解bindActionCreators
这个方法其实也是一个工具函数,可以帮助我们去使用action
function addTodoWithDispatch(text){ const action = { type:ADD_TODO, text } dispatch(action) }
以上代码表示定义action的同时进行dispatch的操作
dispatch(addTodo(text)) dispatch(completeTodo(text))
那么使用bindCationCreators来实现以上的操作就简便很多,如:
const boundAddTodo = text => dispatch(addTodo(text)) const boundCompleteTodo = text => dispatch(completeTodo(text))
最终演示代码如下:
PureRedux.js
import React from 'react' import {createStore,bindActionCreators,combineReducers} from 'redux' function run(){ // init state const initialState = { count:0 } //create a reducer const counter = (state=initialState,action) => { switch(action.type){ case 'PLUS_ONE': return {count:state.count+1}; case 'MINUS_ONE': return {count:state.count-1}; case 'CUSTOM_COUNT': return{ count:state.count+action.payload.count } default: break; } return state } const todoApp = (state={}) => state //create store const store = createStore(combineReducers({ counter, todoApp })); //cation creator function flusOne(){ return {type:'PLUS_ONE'} } function minusOne(){ return {type:'MINUS_ONE'} } function customCount(count){ return {type:'CUSTOM_COUNT',payload:{count}} } flusOne = bindActionCreators(flusOne,store.dispatch) store.subscribe(() => console.log(store.getState())) // store.dispatch(flusOne()); flusOne(); store.dispatch(minusOne()) store.dispatch(customCount(5)) } export default () => ( <div> <button onClick={run}> Run </button> <p> --请打开控制台查看运行结果 </p> </div> )
App.js
import React from 'react' import PureRedux from './PureRedux' class App extends React.Component{ render(){ return( <div> <PureRedux></PureRedux> </div> ) } } export default App
总结
- 对于应用的全局状态进行管理,是在进行web开发中很重要的一定,这样可以让我们统一去做维护,像VueJs的vuex,可以结合React使用的Redux等。
- 在传统的MVC模式中,可能一个view对应多个model,或是多个view对应一个model,当应用变得复杂的时候,这样的管理是很乱其不易维护的,而redux则是利用一个外界仓库(store),来对应用的状态进行统一管理(单向数据流),当用户操作UI想改变某个state的时候,必须通过dispatch(action)去操作,最后通过store对象的subscribe方法去进行UI的更新。
- 当一个应用中有多个reducer(纯函数,用来根据action改变state)的时候,可以通过redux中的combineReducers来对多个reducer进行封装管理。