ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Redux-thunk和Redux-saga的入门级使用

2021-09-16 18:02:44  阅读:220  来源: 互联网

标签:const GET saga LIST VALUE thunk export action Redux


Redux-thunk的使用

实现思路

在action中设置一个为函数的action,因为thunk中间件可以执行action函数。

本示例的表达的意思:

  • 页面需要获取到接口中的data数据,调用getListDataAction函数。
  • getListDataAction函数返回的参数不是一个对象,而是一个函数。
  • 这个action派发后,thunk中间件识别后,会执行该函数,在异步获取到数据后,会再派发type为GET_LIST_DATA的action。
  • store会再次收到一个新的action,在这个action中,store会去匹配reducer中的内容,执行相应的操作后,返回一个新的state。
  • 页面订阅了state的变化,通过setState改变了state,从而将数据存储到state中,页面也会自动刷新。

安装redux-thunk

npm install redux-thunk
// 或者
yarn add redux-thunk

在store文件中使用

github上的redux-thunk地址

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

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

const enhancer = composeEnhancers(
    applyMiddleware(thunk)
);

const store = createStore(reduer, enhancer);

export default store;

在action文件中定义

import axios from "axios";
import { ADD_VALUE, CHANG_VALUE, DEL_VALUE, GET_LIST_DATA, GET_LIST } from "./actiontypes";
export const getChangeAction = (e) => {
    return {
        type: CHANG_VALUE,
        value: e.target.value
    };
}

export const getAddAction = () => {
    return {
        type: ADD_VALUE
    };
}

export const getDelAction = (index) => {
    return {
        type: DEL_VALUE,
        index
    };
}
export const getList = () => {
    return {
        type: GET_LIST
    }
}

export const getListData = (data) => {
    return {
        type: GET_LIST_DATA,
        data
    }
}

export const getListDataAction = () => {
// 默认store只能识别对象的action,但是使用了thunk,可以通过传入一个函数,在thunk中间件中会执行
    return (dispatch) => {
        axios.get("api/todolist").then(res => {
            const action = getListData(res.data);
            dispatch(action);
        }).catch((e) => {
            console.log("获取数据失败了", e)
        })
    }
}

在页面组件中使用

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

Redux-saga的使用

实现源码git地址,分支是redux-saga

实现的思路

首先需要在store中创建saga中间件,该中间件用于监控当前页面中派发的action,根据action中的type参数进行筛选,匹配成功的则执行对应的函数。
设置好了saga之后,页面中根据不同的情况,派发不同的action,当store获取到action之后,saga中间件就会执行,在对应的函数中执行完成后,可以再派发action,用于执行下一步操作。

本示例的意思就是:

  • 页面想要获取到接口中的list数据,所以派发type为GET_LIST 的action。
  • 当store要执行派发的action的时候,根据saga中间件中的内容,如果有监控GET_LIST的函数,那么就要执行函数getListData。
  • 在函数getListData中,发送了axios请求,获取到数据了,那么我需要将获取到的数据存到state中,所以,请求成功后,我需要再派发type为GET_LIST_DATA 的action。
  • store会再次收到一个新的action,在这个action中,store会去匹配reducer中的内容,执行相应的操作后,返回一个新的state。
  • 页面订阅了state的变化,通过setState改变了state,从而将数据存储到state中,页面也会自动刷新。

安装 redux-saga

yarn add redux-saga
// 或者
npm install redux-saga

在store文件中使用

github上的redux-saga地址

import { createStore, applyMiddleware, compose } from 'redux';
// 
import createSagaMiddleware from 'redux-saga'
import reduer from "./reduer";
import mySaga from './sagas'

// 创建saga中间件
const sagaMiddleware = createSagaMiddleware();

// 此处内容是为了实现react-devtools的调试,配置内容参考:https://github.com/zalmoxisus/redux-devtools-extension
const composeEnhancers =
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
        window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
    applyMiddleware(sagaMiddleware)
);

const store = createStore(reduer, enhancer);

// 执行中间件
sagaMiddleware.run(mySaga)
export default store;

创建sagas文件

import { put, takeEvery } from "redux-saga/effects";
import { GET_LIST } from "./actiontypes";
import { getListDataAction } from "./renderStore"
import axios from "axios";

// 获取数据的函数
function* getListData() {
  try {
    // 使用异步的方式,拿到请求的结果
    const res = yield axios.get("api/todolist");
    // 获取到新的action
    const action = getListDataAction(res.data);
    // 派发新的action
    yield put (action)
  } catch (error) {
    console.log("请求todolist数据失败了", error);
  }
}

// 监控派发内容是 GET_LIST,都要执行一次 getListData函数
function* mySaga() {
  yield takeEvery(GET_LIST, getListData);
}
export default mySaga;

在页面组件中使用

// 在生命周期函数中执行
componentDidMount() {
    const action = getList();
    store.dispatch(action)
}

Redux公共部分

actiontypes.js文件内容

export const CHANG_VALUE = "change_value"; 
export const ADD_VALUE = "add_value";
export const DEL_VALUE = "del_value";
export const GET_LIST_DATA = "get_list_data";
export const GET_LIST = "get_list";

rederStore.js中的内容

import { ADD_VALUE, CHANG_VALUE, DEL_VALUE, GET_LIST_DATA, GET_LIST } from "./actiontypes";
export const getChangeAction = e => {
    return {
        type: CHANG_VALUE,
        value: e.target.value
    };
}

export const getAddAction = () => {
    return {
        type: ADD_VALUE
    };
}

export const getDelAction = index => {
    return {
        type: DEL_VALUE,
        index
    };
}
export const getList = () => {
    return {
        type: GET_LIST
    }
}
export const getListDataAction = data => {
    return {
        type: GET_LIST_DATA,
        data
    }
}

reducer.js内容

import { CHANG_VALUE, ADD_VALUE, DEL_VALUE, GET_LIST_DATA } from "./actiontypes";

const defaultState = {
    inputValue: "",
    list: []
};

// eslint-disable-next-line import/no-anonymous-default-export
export default ((state = defaultState, action: any) => {
    if (action.type === CHANG_VALUE) {
        const newState = JSON.parse(JSON.stringify(state));
        newState.inputValue = action.value;
        return newState
    }
    if (action.type === ADD_VALUE) {
        const newState = JSON.parse(JSON.stringify(state));
        newState.list.push(state.inputValue);
        newState.inputValue = "";
        return newState
    }
    if (action.type === DEL_VALUE) {
        const newState = JSON.parse(JSON.stringify(state));
        newState.list.splice(action.index, 1);
        return newState
    }
    if(action.type === GET_LIST_DATA) {
        const newState = JSON.parse(JSON.stringify(state));
        newState.list = action.data;
        return newState
    }
    return state
});

标签:const,GET,saga,LIST,VALUE,thunk,export,action,Redux
来源: https://blog.csdn.net/qq_43403486/article/details/120332307

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有