美文网首页纵横研究院React技术专题社区
【学习笔记 】React ⑦ 使用Redux中间件处理异步流

【学习笔记 】React ⑦ 使用Redux中间件处理异步流

作者: Moombahton | 来源:发表于2019-12-16 16:08 被阅读0次

    在最开始编写项目代码的时候,ajax请求放在生命周期函数componentDidMount()中,但是随着代码量增加,componentDidMount()中有越来越多的逻辑,因此引入中间件middleware,将ajax请求做统一管理,复杂的逻辑放在action处理对之后维护以后以自动化测试都提供了很大的帮助。

何为中间件?

It provides a third-party extension point between dispatching an action, and the moment it reaches the reducer. People use Redux middleware for logging, crash reporting, talking to an asynchronous API, routing, and more.
Redux中间件在派发action以及它到达reducer之间提供了第三方扩展。使用Redux中间件进行日志记录、崩溃报告、与异步API交谈、路由等等。

引自:https://redux.js.org/advanced/middleware

    简单来说middleware指的是actionstore之间,对dispatch的封装和升级,使用middleware之后,action既可以是一个对象,也可以是一个函数

增加中间件后的数据流

Redux标准流程
1.页面派发一个action
2.通过dispatch方法派发给store(action是一个对象)
3.store接收到action,连同之前的state传给reducer
4.reducer返回一个新的数据给store
5.store去改变自己的state

增加middleware之后,Data Flow是下图这样的

Redux Data Flow

    使用Redux中间件后流程,调用dispatch()方法,根据参数的不同,执行不同的流程。如果参数是对象就把这个对象直接传递给store,如果参数是函数,就先执行这个函数,执行之后如果需要调用store,那这个函数再去调用store

Redux处理异步流

  • redux-thunk

github:https://github.com/reduxjs/redux-thunk

1.安装redux-thunk

yarn add redux-thunk
  1. 修改store的配置
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import thunk from 'redux-thunk'

const composeEnhancers =
    typeof window === 'object' &&
    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
// https://github.com/zalmoxisus/redux-devtools-extension

3.在action中编写写异步的代码(action可以返回一个函数啦🤣)

export  const getTodoList = () => {
    return () => {
        axios.get('http://mock-api.com/Rz317OnM.mock/api/todolist')
            .then((res) => {
                console.log(res.data)
            })
            .catch( () => {alert('error')})
    }
}

4.通过reducer更新store中的数据

export  const getTodoList = () => {
    return (dispatch) => {
        axios.get('http://mock-api.com/Rz317OnM.mock/api/todolist')
            .then((res) => {
                console.log(res.data)
                const data = res.data
                const action = initListAction(data)
                dispatch(action)
            })
            .catch( () => {alert('error')})
    }
}

5.Todolist.js获取数据

import { getInputChangeAction, getAddItemAction, getDeleteItemAction, getTodoList } from './store/actionCreators'

 componentDidMount () {
        const action = getTodoList()
        store.dispatch(action)
        console.log(action)
    }
  • redux-saga

适用于非常大型复杂的项目
github:https://github.com/redux-saga/redux-saga

1.安装redux-saga

yarn add redux-saga

2.配置store/index.js

import { createStore, applyMiddleware, compose } from 'redux'
import createSagaMiddleware from 'redux-saga'
import reducer from './reducer'
import todoSagas from './sagas'

const sagaMiddleware = createSagaMiddleware()
const composeEnhancers =
   typeof window === 'object' &&
   window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware));
const store = createStore(reducer, enhancer);
sagaMiddleware.run(todoSagas)

export default store

3.创建sagas.js文件

//sagas文件一定要有 generator 函数
function* mySaga() {
}
export default mySaga;

4.修改Todolist.js中获取数据的方法

  componentDidMount () {
        const action = getInitList()
        console.log(action)
        store.dispatch(action)
    }

5.补充逻辑
actionTypes.js

export const GET_INIT_LIST = 'get_init_list'

actionCreator.js

export const getInitList = () => ({
    type: GET_INIT_LIST
})

sagas.js

import { takeEvery, put } from 'redux-saga/effects'
import { GET_INIT_LIST } from './actionTypes'
import axios from 'axios'
import { initListAction } from './actionCreators'
function* getInitList() {
    try{
        const res = yield axios.get('http://mock-api.com/Rz317OnM.mock/api/todolist')
        const action = initListAction(res.data)
        yield put(action)
    } catch(e) {
        console.log('网络请求失败')
    }
}

// generator 函数
function* mySaga() {
    yield takeEvery(GET_INIT_LIST, getInitList);
}

export default mySaga;

(完)

相关文章

  • 【学习笔记 】React ⑦ 使用Redux中间件处理异步流

        在最开始编写项目代码的时候,ajax请求放在生命周期函数componentDidMount()中,但是随着...

  • redux

    使用步骤 redux只处理同步 redux处理异步请求中间件· 在引入redux的时候引入applyMiddlew...

  • react-redux基本使用

    安装: npm install react-redux --save 异步任务中间件:redux-thunk re...

  • redux-thunk

    redux-thunk 是一款redux中间件 工作流程 目前是先处理异步在派发动作 使用 redux-thunk...

  • Redux中间件

    在React中,常用Redux来做一些业务逻辑处理。Redux提供了中间件的写法,可以对Redux中的数据流做一些...

  • React-依赖

    create-react-app 初始化空的react项目 redux-saga 处理异步利器 redux-seq...

  • [React Native Error]Unhandled JS

    使用Redux 进行异步操作报错 解决 使用自定义中间件(middleware)来支持异步 action。

  • React学习笔记4-深入Redux

    这篇六个点:1 Redux简介 2 中间件 3 异步流 4 Redux与路由 5 Redux与组件 6 应用实例。...

  • 深入浅出redux-middleware

    多数redux初学者都会使用redux-thunk这个中间件来处理异步请求(比如我) 本来写这篇文章只是想写写re...

  • react --- redux使用

    react-reduxReact插件,作用:方便在React项目中使用Redux react-thunk中间件,作...

网友评论

    本文标题:【学习笔记 】React ⑦ 使用Redux中间件处理异步流

    本文链接:https://www.haomeiwen.com/subject/ixbrnctx.html