利用Redux-thunk中间件实现ajax数据请求&Redux的使用

准备工作

利用Redux-thunk中间件实现ajax数据请求&Redux的使用_第1张图片

在index.js中创建store

import {
     createStore} from 'redux';
import reducer from './reducer';

const store=createStore(reducer);

export default store;

store中最原始的数据
在这里插入图片描述

此时的TodoList如下:
利用Redux-thunk中间件实现ajax数据请求&Redux的使用_第2张图片

服务端返回一个数组:[‘Amethyst’,‘Lecheng’,‘Forever’]

const express=require('express');
const app=express();

app.get('/data',(request,response)=>{
     
    response.setHeader('Access-Control-Allow-Origin','*');
    var data=['Amethyst','Lecheng','Forever'];
    response.send(data);
})

app.listen('5000',()=>{
     
    console.log('5000端口监听中...');
})

需求:用ajax获取服务端返回的数组,并且显示在TodoList的列表中

未使用redux-thunk的情况

首先,在actionTypes.js中定义action类型

export const HANDLE_AJAX_RES='handle_ajax_res';

在actionCreator.js中创建action
这里使用常量而不直接使用字符串的原因是便于debug(写字符串的话单词写错不会报错)
在actionCreator中统一创建action便于维护

import {
     HANDLE_AJAX_RES} from './actionTypes';
export let getHandleAjaxAction=(value)=>({
     
    type:HANDLE_AJAX_RES,
    value //用于传递获取的数据
});

接下来在antdTodoList.js中利用react的生命周期函数componentDidMount发送ajax请求(写在componentDidMount中是因为它只执行一次)

import axios from 'axios';
componentDidMount(){
     
   axios.get('http://localhost:5000/data').then((response)=>{
     
       const action=getHandleAjaxAction(response.data);
       store.dispatch(action);
   }).catch(()=>alert('error'));
}

然后在reducer.js中处理action,返回一个新的state给store

import {
     HANDLE_AJAX_RES} from './actionTypes';

const defaultState={
     
    inputValue:'',
    list:[]
}

let func=(state=defaultState,action)=>{
     
    if(action.type===HANDLE_AJAX_RES){
     
        const newState=JSON.parse(JSON.stringify(state));
        newState.list=[...action.value];
        return newState;
    }
    return state;
}

export default func;

在antdTodoList.js中,利用store.sunscribe方法监听store内的数据变化,并且用新的数据替换旧的数据
利用Redux-thunk中间件实现ajax数据请求&Redux的使用_第3张图片

这样便完成了需求(此处省略了遍历list设置item的内容),效果如下:
利用Redux-thunk中间件实现ajax数据请求&Redux的使用_第4张图片

使用Redux-thunk中间件

一般情况下创建action只能返回对象,引入redux-thunk之后,不仅可以返回对象,还可以返回函数,如果在生命周期函数中放过多的异步请求会使得组件越来越大,因此我们可以把异步请求或复杂的业务逻辑放在action里面统一管理,也便于自动化测试

首先,安装redux-thunk,在创建store的时候引入(这种写法是便于使用Redux-Devtools)

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

const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?   
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
     
    }) : compose;

const enhancer = composeEnhancers(
  applyMiddleware(thunk),
);

//const store = createStore(reducer,applyMiddleware(thunk));
const store = createStore(reducer, enhancer);

export default store;

接下来在actionCreator.js中创建一个action发送ajax请求并把获取的数据传递出去
返回的这个函数会自动接收到store.dispatch方法,可以直接使用dispatch参数传递action

export let getHandleAjaxAction=(value)=>({
     
    type:HANDLE_AJAX_RES,
    value
});

export let getData=()=>{
     
    return (dispatch)=>{
     
        axios.get('http://localhost:5000/data').then((response)=>{
     
            const action=getHandleAjaxAction(response.data);
            dispatch(action);
        }).catch(()=>alert('error'));
    }
}

最后再到componentDidMount函数中调用store.dispatch将action传递到store
调用store.dispatch传递action的时候,action所对应的函数会自动执行

componentDidMount(){
     
    const action=getData();
    store.dispatch(action);
}

Over~
再来看看效果:
利用Redux-thunk中间件实现ajax数据请求&Redux的使用_第5张图片
利用Redux-thunk中间件实现ajax数据请求&Redux的使用_第6张图片

你可能感兴趣的:(Redux)