一、课程目标
- Redux 基础概念(Action、Reducer、State)
- 异步Action的处理
- Redux中间件原理
二、知识要点
1. 搭建环境
# 创建项目
npx create-react-app redux
#or
create-react-app redux
1. 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.3 第三方中间件
// 可以利用
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