使用redux-thunk中间件实现ajax数据请求

上片文章,如果把一些复杂逻辑或者异步请求,放在同一个组件中,会显得冗长和难以管理。

我们可以使用react-thunk这个中间件进行管理。

 

可以把逻辑放在action中

 

优势:自动化测试特别方便

 

首先,学会使用:

redux-thunk

 

Installation
npm install redux-thunk
Then, to enable Redux Thunk, use applyMiddleware():

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';

// Note: this API requires redux@>=3.1.0
const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

这个是redux devtools的 插件的使用的代码,要带上

 

 

如果只是使用thunk插件,那就:

import {createStore,applyMiddleware} from 'redux';
import reducer from './reducer';
import thunk from "redux-thunk";

/**
 * 在创建store的时候使用reducer构建初始数据
 * 在创建的时候会使用thunk和__REDUX_DEVTOOLS_EXTENSION__ 中间件
 * 这里的中间件指的是redux的中间件,而不是react
 * 
 */
const store = createStore(reducer, applyMiddleware(thunk));

export default store;

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

 

如果使用thunk和redux devtools插件,那就

redux-devtools-extension

1.2 Advanced store setup
If you setup your store with middleware and enhancers, change:

  import { createStore, applyMiddleware, compose } from 'redux';

+ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
+ const store = createStore(reducer, /* preloadedState, */ composeEnhancers(
- const store = createStore(reducer, /* preloadedState, */ compose(
    applyMiddleware(...middleware)
  ));

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

const composeEnhancers =
  typeof window === 'object' &&
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?   
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
      // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
    }) : compose;

const enhancer = composeEnhancers(
  applyMiddleware(...middleware),
  // other store enhancers if any
);
const store = createStore(reducer, enhancer);

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

实际上配置store.js的代码:

import { createStore, applyMiddleware, compose } from "redux";
import reducer from './reducer';
import thunk from "redux-thunk";

/**
 * 在创建store的时候使用reducer构建初始数据
 * 在创建的时候会使用thunk和__REDUX_DEVTOOLS_EXTENSION__ 中间件
 * 这里的中间件指的是redux的中间件,而不是react
 * 
 */
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
    : compose;

const enhancer = composeEnhancers(
  applyMiddleware(thunk)
  // other store enhancers if any
);

const store = createStore(reducer, enhancer);

export default store;

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

 

 

然后我们修改todolist组件中的代码,我们可以把componentDidMount中的代码移除,移动到action中去。

*当时候redux-thunk之后,我们当action可以是一个函数了。

修改如下:

actionCreaters.js

import {
  CHANGE_INPUT_VALUE,
  ADD_TODO_ITEM,
  DELETE_TODO_ITEM,
  INIT_LIST_ACTION
} from "./actionTypes";
import axios from 'axios';

export const getInputChangeValue = (value) => ({
        type: CHANGE_INPUT_VALUE,
        value:value
});

export const getAddItemAction = () => ({
         type: ADD_TODO_ITEM,
});

export const getDeleteItemAction = (index) => ({
         type: DELETE_TODO_ITEM,
         index
});

export const initListAction = (data) => ({
         type: INIT_LIST_ACTION,
         data
});

export const getTodoList = () => {
  return (dispatch) => {
    axios("http://localhost:3000/mock/list.json")
      .then(res => {
        const data = res.data;
        // 改变store中的数据
        const action = initListAction(data);
        dispatch(action);
      })
      .catch(err => {
        console.log(err);
      });
  }
};

因为在配置文件中我已经配置了axios的原型链,正常的话使用是this.axios就可以使用了。但是在这里不知道为啥子不好用,就采用常规办法吧。

 

 

修改todolist.js

核心代码:

componentDidMount() {
      const action = getTodoList();
    //   当调用store.dispatch把action发给store的时候,action会自动执行。
      store.dispatch(action);
      console.log(action);
  }

 

 

//这个算是redux进阶的Demo
import React, { Component } from "react";
import store from "../../store";
import {
  getInputChangeValue,
  getAddItemAction,
  getDeleteItemAction,
  initListAction,
  getTodoList
} from "../../store/actionCreaters";
import ToDoListUI from './ToDoListUI';

class ToDoListUp extends Component {
  constructor(props) {
    super(props);
    this.state = store.getState();
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleStoreChange = this.handleStoreChange.bind(this);
    this.handleButtonClick = this.handleButtonClick.bind(this);
    /**
     * 页面上的内容并没有随着store的更新而更新,所以如下操作:
     * store发生改变,则subscribe()绑定的函数会自动执行
     */
    store.subscribe(this.handleStoreChange);
  }

  componentDidMount() {
      const action = getTodoList();
    //   当调用store.dispatch把action发给store的时候,action会自动执行。
      store.dispatch(action);
      console.log(action);
  }

  // input值改变触发action
  handleInputChange(e) {
    //定义action两种方式,下面是最原始的一种:(1)
    // const action = {
    //   type: CHANGE_INPUT_VALUE,
    //   value: e.target.value
    // };
    //下面是改进的方式:(2)
    const action = getInputChangeValue(e.target.value);
    store.dispatch(action);

    console.log(e.target.value);
  }
  // 重新渲染页面数据
  handleStoreChange() {
    this.setState(store.getState());
  }
  // 提交输入内容
  handleButtonClick() {
    const action = getAddItemAction();

    store.dispatch(action);
  }
  // 点击列表电影名字,会删除电影
  handleItemDelete(index) {
    const action = getDeleteItemAction(index);
    store.dispatch(action);
  }

  render() {
    return (
      <ToDoListUI
        list={this.state.list}
        inputValue={this.state.inputValue}
        handleInputChange={this.handleInputChange}
        handleButtonClick={this.handleButtonClick}
        handleItemDelete={this.handleItemDelete}
      />
    );
  }
}

export default ToDoListUp;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
redux-thunk是一个用于处理异步操作的Redux中间件。它允许我们在Redux中编写异步逻辑,并且可以在action creators中返回函数而不仅仅是一个普通的action对象。 使用redux-thunk,首先要安装它: ``` npm install redux-thunk ``` 然后,在创建store时将thunk作为middleware应用到Redux store中: ```javascript import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import rootReducer from './reducers'; const store = createStore(rootReducer, applyMiddleware(thunk)); ``` 接下来,你可以在action creators中返回一个函数,而不仅仅是一个普通的action对象。这个函数可以接收dispatch和getState作为参数,允许你执行异步操作并在适当的时机分发action。 例如,你可以创建一个异步的action creator来获取数据: ```javascript const fetchData = () => { return (dispatch, getState) => { dispatch({ type: 'FETCH_DATA_START' }); // 异步请求数据并处理响应 fetch('https://api.example.com/data') .then(response => response.json()) .then(data => { dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data }); }) .catch(error => { dispatch({ type: 'FETCH_DATA_FAILURE', payload: error }); }); }; }; ``` 在上面的例子中,我们返回了一个函数,该函数接收dispatch和getState作为参数。在函数体内,我们可以执行异步操作(例如发起网络请求),并在适当的情况下分发相应的action。 使用redux-thunk,你的action creators可以更灵活地处理异步逻辑,并且能够与Redux无缝地集成。希望这个回答对你有帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值