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;
    
    
  • 相关阅读:
    Civil 3D 二次开发 创建Civil 3D 对象—— 01 —— 创建几何空间点
    Civil 3D 二次开发 创建Civil 3D 对象—— 00 ——
    Civil 3D 二次开发 创建AutoCAD对象—— 01 —— 创建直线
    Civil 3D 二次开发 新建CLR项目出现错误C2143
    Civil 3D 二次开发 创建AutoCAD对象—— 00 ——
    了解AutoCAD对象层次结构 —— 6 ——块表记录
    datepicker97使用
    使用angular 外接 templateUrl,使用ng-include
    angularJs 遮罩
    网上找的有关css兼容问题
  • 原文地址:https://www.cnblogs.com/boye-1990/p/11468473.html
Copyright © 2011-2022 走看看