一、课程目标
- Redux 基础概念(Action、Reducer、State)
- 异步Action的处理
- Redux中间件原理
二、知识要点
1. 搭建环境
# 创建项目 npx create-react-app redux #or create-react-app redux
2.Redux入门
JavaScript 需要管理比任何时候都要多的 state (状态)。
1.1 统一状态管理需要完成什么功能
- 更新状态
- 获取状态
- 状态变更通知 - (最好是订阅发布模式)
1.2 演示
// store.js import { createStore } from 'redux' const action = { clear: { type: 'clear' }, add: { type: 'add', payload: 1 }, } const reducer = (state = { num: 100 }, action) => { switch (action.type) { case 'clear': return { num: 0 } case 'add': return { num: state.num + action.payload } default: return state } } const store = createStore( reducer ) // 建立响应订阅 store.subscribe(() => console.log('update', store.getState())) store.dispatch(action['clear']) store.dispatch(action['add']) //App.js import React from 'react' import store from './store' class App extends React.Component{ render(){ return <div> </div> } } export default App
1.3 总结三大原则
- 单一数据源
整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
- State 是只读的
唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
- 使用纯函数来执行修改
为了描述 action 如何改变 state tree ,你需要编写 reducers。
** **
3. 异步Action
const action = { // ... asyncAdd: dispatch => { setTimeout(() => { dispatch({ type: 'add', payload: 2 }) }, 1000) } } // action['asyncAdd'](store.dispatch) store.dispatch(action['asyncAdd'])
4. Redux中间件
4.1 logger 与 thunk
import { createStore, applyMiddleware } from 'redux' const logger = ({ dispatch, getState }) => next => action => { console.log('start: ' ,action) next(action) console.log('end: ' ,action) return } const thunk = ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch) } next(action) return } const store = createStore( reducer, applyMiddleware(...[ logger, thunk ]) ) // 可以利用 // import logger from 'redux-logger' // import thunk from 'redux-thunk' // const store = createStore( // reducer, // applyMiddleware(...[ // logger, // thunk // ]) // )
4.2 第三方中间件
// 可以利用 import logger from 'redux-logger' import thunk from 'redux-thunk' const store = createStore( reducer, applyMiddleware(...[ logger, thunk ]) )
5 与React结合
import React from 'react' import store from './store' import ReactDom from 'react-dom' const render = () => { ReactDom.render( <App />, document.querySelector('#root') ) } store.subscribe(render) class App extends React.Component { render() { return <div><div> <p>{store.getState().num}</p> <div> <button onClick={() => store.dispatch({ type: "clear" })}>clear</button> <button onClick={() => store.dispatch({ type: "add", payload: 1 })}>add</button> <button onClick={() => { store.dispatch(dispatch => { setTimeout(() => { dispatch({ type: "add", payload: 2 }) }, 1000) }) } }>asyncAdd</button> </div> </div> </div> } } export default App