zoukankan      html  css  js  c++  java
  • 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可以是一个函数
    /**
     * store就像一个图书管理员,在接到组件(借书人)派发的 dispatch(借书人说的话) 时,
     * 他本身不知道书在什么位置,有没有这本书,需要查询 reducer (图书列表)
     */
    import { createStore, applyMiddleware, compose } from 'redux'
    import thunk from 'redux-thunk'
    import todoListReducer from './reducer' // 引入图书列表
    
    // 使用redux-devtools中间件和redux-thunk中间件
    
    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose
    const enhancer = composeEnhancers(
        applyMiddleware(thunk)
    )
    const store = createStore(
        todoListReducer,
        enhancer
    ) // 查询图书列表
    
    export default store
    

    使用redux-thunk

    • 在项目中使用引入使用redux-thunk之后
    • 在actionCreators中创建action不再只能创建对象action了,能够创建函数形式的action
    • 因为action能是个函数,所以我们可以把异步请求放在action中而不是放在生命周期函数里面
    • 项目大的时候逻辑复杂的时候,异步请求放在钩子函数里是不好的
    import { CHANGE_INPUT_VALUE, CHANGE_LIST_VALUE, DELETE_LIST_VALUE, INIT_DATA } from './actionTypes'
    import mockData from '../mockjs/mock';
    import axios from 'axios'
    
    export const getInputChangeValue = (value) => ({
        type: CHANGE_INPUT_VALUE,
        value
    })
    
    export const getAddTodoListValue = (item) => ({
        type: CHANGE_LIST_VALUE,
        item
    })
    
    export const getDeletTodoListValue = (index) => ({
        type: DELETE_LIST_VALUE,
        index
    })
    
    export const initData = (data) => ({
        type: INIT_DATA,
        data
    })
    /**
     * 因为使用了redux-thunk所以在actionCreators中的箭头函数可以返回一个函数
     */
    export const getToduList = () => {
        return (dispatch) => { // 这个action返回的是这样一个箭头函数,在使用的时候同样页需要通过dispatch派发,箭头函数中dispath其实就是在派发这个action的时候传递进来的
            axios.get('http://getTodoList', {dataType: 'json'}).then(res => {
                const action = initData(res.data.data)
                dispatch(action)
            })
        }
    }
    

    在组件中使用这个异步请求

    • 在componentDidMount函数中使用了
    /**
     * 组件就是一个需要借书的人,通过 dispatch 传达 action (书名)给图书管理员(store)
     */
    
    import React, { Component }from 'react';
    import { message } from "antd";
    import store from './store'; // 引入图书管理员 store
    import AppUi from './AppUi';
    // import mockData from './mockjs/mock';
    // import axios from 'axios'
    // 引入action
    import { getInputChangeValue, getAddTodoListValue, getDeletTodoListValue, getToduList } from './store/actionCreators'
    // import { CHANGE_INPUT_VALUE, CHANGE_LIST_VALUE, DELETE_LIST_VALUE } from './store/actionTypes'
    import "antd/dist/antd.css";
    class App extends Component {
      constructor(props){
        super(props)
        this.state = store.getState()
        console.log(store.getState())
        this.handleInputChange = this.handleInputChange.bind(this);
        this.addTodoList = this.addTodoList.bind(this);
        this.handleStroeChange = this.handleStroeChange.bind(this);
        this.deletTodoList = this.deletTodoList.bind(this);
        store.subscribe(this.handleStroeChange) // 图书管理员会随时通知各个借书人,图书馆书籍的变化
      }
      componentDidMount (){
        // 引入了actionCreators中的getToduList方法,他返回的是一个函数action
        const action = getToduList()
        // 所以这里使用dispact去派发这个action
        store.dispatch(action)
        /*
        axios.get('http://getTodoList', {dataType: 'json'}).then(res => {
          console.log(res.data.data)
          this.init(res.data.data)
          console.log(this.state)
        })
        */
      }
      render() {
        return (
          <AppUi
          inputValue = {this.state.inputValue}
          handleInputChange = {this.handleInputChange}
          deletTodoList = {this.deletTodoList}
          addTodoList = {this.addTodoList}
          list = {this.state.list}
          />
        )
      }
      handleInputChange(e) {
        /*
        const action = {
          type: CHANGE_INPUT_VALUE, // 借什么书
          value: e.target.value
        }
        */
        const action = getInputChangeValue(e.target.value)
        store.dispatch(action); // 传达给store
        console.log(e.target.value)
      }
      /*
      // 数据初始化
      init(data) {
        const action = initData(data)
        store.dispatch(action)
      }
      */
      // 添加
      addTodoList() {
        /*
        if (this.state.inputValue) {
          const action = {
            type: CHANGE_LIST_VALUE,
            item: this.state.inputValue
          }
          store.dispatch(action)
        } else {
          message.warning('请输入内容');
        }
        */
       if (this.state.inputValue) {
          const action = getAddTodoListValue(this.state.inputValue)
          store.dispatch(action)
       } else {
        message.warning('请输入内容');
       }
      }
      // 删除
      deletTodoList(index) {
        /*
        const action = {
          type: DELETE_LIST_VALUE,
          value: index
        }
        */
       console.log(index)
        const action = getDeletTodoListValue(index)
        store.dispatch(action)
      }
      handleStroeChange() {
        this.setState(store.getState()) // 每当图书馆有变化的时候,图书管理员(store)通过这个方式告诉借书人(组件)
      }
    }
    
    export default App;
    
    
  • 相关阅读:
    第三次上机
    第5次作业
    第二次上机练习
    第三次作业
    第一次作业
    第一次作业
    第二次上机练习
    第二次作业
    第一次作业
    第四周作业
  • 原文地址:https://www.cnblogs.com/boye-1990/p/11468473.html
Copyright © 2011-2022 走看看