react入門系列之使用redux-thunk中間件發起異步請求

### redux-thunk

- redux-thunk是redux中的一箇中間件
- 安裝命令 yarn add redux-thunk
- 在store文件夾中的index.js中引入applyMiddleware,這樣咱們才能使用中間件
- 而後再引入redux-thunk
- 並在createStore中使用applyMiddleware(thunk)

#### 到底生命是redux中間件

- 誰和誰之間
- action和store之間
- 其實中間件就是對dispath一個封裝
- 若是傳遞的是一個函數,會讓這個函數先執行再傳遞給store
- 若是是一個對象,就直接傳遞給store
- 因此使用thunk中間件之後action能夠是一個函數
 1 /**
 2 * store就像一個圖書管理員,在接到組件(借書人)派發的 dispatch(借書人說的話) 時,
 3 * 他自己不知道書在什麼位置,有沒有這本書,須要查詢 reducer (圖書列表)
 4 */
 5 import { createStore, applyMiddleware, compose } from 'redux'
 6 import thunk from 'redux-thunk'
 7 import todoListReducer from './reducer' // 引入圖書列表
 8 
 9 
10 // 使用redux-devtools中間件和redux-thunk中間件
11 
12 
13 const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose
14 const enhancer = composeEnhancers(
15 applyMiddleware(thunk)
16 )
17 const store = createStore(
18 todoListReducer,
19 enhancer
20 ) // 查詢圖書列表
21 
22 
23 export default store

 

### 使用redux-thunk

- 在項目中使用引入使用redux-thunk以後
- 在actionCreators中建立action再也不只能建立對象action了,可以建立函數形式的action
- 由於action能是個函數,因此咱們能夠把異步請求放在action中而不是放在生命週期函數裏面
- 項目大的時候邏輯複雜的時候,異步請求放在鉤子函數裏是很差的
 1 import { CHANGE_INPUT_VALUE, CHANGE_LIST_VALUE, DELETE_LIST_VALUE, INIT_DATA } from './actionTypes'
 2 import mockData from '../mockjs/mock';
 3 import axios from 'axios'
 4 
 5 
 6 export const getInputChangeValue = (value) => ({
 7 type: CHANGE_INPUT_VALUE,
 8 value
 9 })
10 
11 
12 export const getAddTodoListValue = (item) => ({
13 type: CHANGE_LIST_VALUE,
14 item
15 })
16 
17 
18 export const getDeletTodoListValue = (index) => ({
19 type: DELETE_LIST_VALUE,
20 index
21 })
22 
23 
24 export const initData = (data) => ({
25 type: INIT_DATA,
26 data
27 })
28 /**
29 * 由於使用了redux-thunk因此在actionCreators中的箭頭函數能夠返回一個函數
30 */
31 export const getToduList = () => {
32 return (dispatch) => { // 這個action返回的是這樣一個箭頭函數,在使用的時候一樣頁須要經過dispatch派發,箭頭函數中dispath其實就是在派發這個action的時候傳遞進來的
33 axios.get('http://getTodoList', {dataType: 'json'}).then(res => {
34 const action = initData(res.data.data)
35 dispatch(action)
36 })
37 }
38 }

 

### 在組件中使用這個異步請求
 
- 在componentDidMount函數中使用了
  1 /**
  2 * 組件就是一個須要借書的人,經過 dispatch 傳達 action (書名)給圖書管理員(store)
  3 */
  4 
  5 import React, { Component }from 'react';
  6 import { message } from "antd";
  7 import store from './store'; // 引入圖書管理員 store
  8 import AppUi from './AppUi';
  9 // import mockData from './mockjs/mock';
 10 // import axios from 'axios'
 11 // 引入action
 12 import { getInputChangeValue, getAddTodoListValue, getDeletTodoListValue, getToduList } from './store/actionCreators'
 13 // import { CHANGE_INPUT_VALUE, CHANGE_LIST_VALUE, DELETE_LIST_VALUE } from './store/actionTypes'
 14 import "antd/dist/antd.css";
 15 class App extends Component {
 16 constructor(props){
 17 super(props)
 18 this.state = store.getState()
 19 console.log(store.getState())
 20 this.handleInputChange = this.handleInputChange.bind(this);
 21 this.addTodoList = this.addTodoList.bind(this);
 22 this.handleStroeChange = this.handleStroeChange.bind(this);
 23 this.deletTodoList = this.deletTodoList.bind(this);
 24 store.subscribe(this.handleStroeChange) // 圖書管理員會隨時通知各個借書人,圖書館書籍的變化
 25 }
 26 componentDidMount (){
 27 // 引入了actionCreators中的getToduList方法,他返回的是一個函數action
 28 const action = getToduList()
 29 // 因此這裏使用dispact去派發這個action
 30 store.dispatch(action)
 31 /*
 32 axios.get('http://getTodoList', {dataType: 'json'}).then(res => {
 33 console.log(res.data.data)
 34 this.init(res.data.data)
 35 console.log(this.state)
 36 })
 37 */
 38 }
 39 render() {
 40 return (
 41 <AppUi
 42 inputValue = {this.state.inputValue}
 43 handleInputChange = {this.handleInputChange}
 44 deletTodoList = {this.deletTodoList}
 45 addTodoList = {this.addTodoList}
 46 list = {this.state.list}
 47 />
 48 )
 49 }
 50 handleInputChange(e) {
 51 /*
 52 const action = {
 53 type: CHANGE_INPUT_VALUE, // 借什麼書
 54 value: e.target.value
 55 }
 56 */
 57 const action = getInputChangeValue(e.target.value)
 58 store.dispatch(action); // 傳達給store
 59 console.log(e.target.value)
 60 }
 61 /*
 62 // 數據初始化
 63 init(data) {
 64 const action = initData(data)
 65 store.dispatch(action)
 66 }
 67 */
 68 // 添加
 69 addTodoList() {
 70 /*
 71 if (this.state.inputValue) {
 72 const action = {
 73 type: CHANGE_LIST_VALUE,
 74 item: this.state.inputValue
 75 }
 76 store.dispatch(action)
 77 } else {
 78 message.warning('請輸入內容');
 79 }
 80 */
 81 if (this.state.inputValue) {
 82 const action = getAddTodoListValue(this.state.inputValue)
 83 store.dispatch(action)
 84 } else {
 85 message.warning('請輸入內容');
 86 }
 87 }
 88 // 刪除
 89 deletTodoList(index) {
 90 /*
 91 const action = {
 92 type: DELETE_LIST_VALUE,
 93 value: index
 94 }
 95 */
 96 console.log(index)
 97 const action = getDeletTodoListValue(index)
 98 store.dispatch(action)
 99 }
100 handleStroeChange() {
101 this.setState(store.getState()) // 每當圖書館有變化的時候,圖書管理員(store)經過這個方式告訴借書人(組件)
102 }
103 }
104 export default App;
相關文章
相關標籤/搜索