redux 中文文档
redux 中文文档
redux 原理图
redux 原理图
redux 三大原则
redux 三大原则
单一数据源
整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
State 是只读的
唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
使用纯函为了
描述 action 如何改变 state tree ,你需要编写 reducers。
计算器案例
目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13
| src ├─components │ └─Count │ └─index.jsx └─redux │ └─constant.js │ └─count_action.js │ └─count_reducer.js │ └─store.js └─App.jsx └─index.js
|
src/index.js
1 2 3 4 5 6 7 8
| import React from 'react' import ReactDOM from 'react-dom' import App from './App' import store from './redux/store'
store.subscribe(() => { ReactDOM.render(<App />, document.getElementById('root')) })
|
src/App.js
1 2 3 4 5 6 7 8 9 10 11 12
| import React, { Component } from 'react' import Count from './components/Count/index'
export default class App extends Component { render() { return ( <div> <Count /> </div> ) } }
|
src/components/Count/index.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| import React, { Component } from 'react'
import store from '../../redux/store'
import { createIncrementAction, createDecrementAction, } from '../../redux/count_action'
class Count extends Component {
increment = () => { const { value } = this.selectNumber store.dispatch(createIncrementAction(value * 1)) } decrement = () => { const { value } = this.selectNumber store.dispatch(createDecrementAction(value * 1)) } incrementIfOdd = () => { const { value } = this.selectNumber const count = store.getState() if (count % 2 !== 0) { store.dispatch(createIncrementAction(value * 1)) } } incrementAsync = () => { const { value } = this.selectNumber store.dispatch(createIncrementAction(value * 1)) } render() { return ( <div> <h1>当前求和为:{store.getState()}</h1> <select ref={(c) => (this.selectNumber = c)}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <button onClick={this.increment}>+</button> <button onClick={this.decrement}>-</button> <button onClick={this.incrementIfOdd}>若当前求和为奇数 +</button> <button onClick={this.incrementAsync}>异步 +</button> </div> ) } }
export default Count
|
src/redux/constant.js
1 2 3 4 5
|
export const INCREMENT = 'increment' export const DECREMENT = 'decrement'
|
src/redux/count_action.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
import { INCREMENT, DECREMENT } from './constant'
export const createIncrementAction = (data) => ({ type: INCREMENT, data }) export const createDecrementAction = (data) => ({ type: DECREMENT, data })
export const createIncrementAsyncAction = (data, time) => { return (dispatch) => { setTimeout(() => { dispatch(createIncrementAction(data)) }, time) } }
|
src/redux/count_reducer.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
import { INCREMENT, DECREMENT } from './constant'
const initState = 0 export default function countReducer(preState = initState, action) { const { type, data } = action switch (type) { case INCREMENT: return preState + data case DECREMENT: return preState - data default: return preState } }
|
src/redux/store.js
异步 store 需要引入 applyMiddleware
1 2 3 4 5 6 7 8 9 10 11 12
|
import { createStore, applyMiddleware } from 'redux'
import countReducer from './count_reducer'
import thunk from 'redux-thunk'
export default createStore(countReducer, applyMiddleware(thunk))
|