redux的中间件的介绍和使用

  • 介绍

Redux中间件是位于派发和归约器之间的扩展点,它可以拦截、处理或修改派发的动作,并且可以对派发的动作进行异步处理。中间件提供了一种灵活的机制,可以在Redux应用中处理各种复杂的业务逻辑和副作用。

  • Redux中常用的中间件有以下几种:

  • Redux Thunk

    • 介绍:Redux Thunk是一个用于处理异步操作的中间件。它允许在动作创建函数中返回一个函数,而不仅仅是一个动作对象。这个返回的函数可以在需要时进行异步操作,例如发起Ajax请求或延迟执行动作。Redux Thunk使得在Redux中处理异步逻辑变得更加简单。
    • 使用:
      • 安装:
      • npm install redux redux-thunk --save
        
      • 在创建Redux存储(store)之前,需要将Redux Thunk中间件应用到Redux存储中。在创建存储之前,通过applyMiddleware方法将Redux Thunk中间件传递给createStore函数。例如:

        import { createStore, applyMiddleware } from 'redux';
        import thunk from 'redux-thunk';
        import rootReducer from './reducers';
        
        const store = createStore(rootReducer, applyMiddleware(thunk));
        

        在上面的示例中,我们将Redux Thunk中间件传递给applyMiddleware函数,然后将其作为第二个参数传递给createStore函数。

      • 现在,你可以创建异步的动作创建函数(action creators)了。异步的动作创建函数可以返回一个函数,而不仅仅是一个动作对象。这个函数可以在需要时进行异步操作,并最终派发一个或多个动作。例如:

        import axios from 'axios';
        
        export const fetchUser = () => {
          return dispatch => {
            dispatch({ type: 'FETCH_USER_REQUEST' });
        
            axios.get('https://api.example.com/users')
              .then(response => {
                dispatch({ type: 'FETCH_USER_SUCCESS', payload: response.data });
              })
              .catch(error => {
                dispatch({ type: 'FETCH_USER_FAILURE', payload: error.message });
              });
          };
        };
        

        在上面的示例中,我们创建了一个fetchUser的异步动作创建函数。它返回一个函数,该函数接收dispatch作为参数。在这个函数中,我们首先派发一个FETCH_USER_REQUEST动作来表示异步操作开始。然后,我们使用axios库发起异步请求,并在请求成功或失败时派发相应的动作。

      • 在组件中使用异步的动作创建函数。你可以在组件中使用connect函数来连接Redux存储,并将异步的动作创建函数映射为组件的属性。例如:

        import React, { useEffect } from 'react';
        import { connect } from 'react-redux';
        import { fetchUser } from './actions';
        
        const UserComponent = ({ user, fetchUser }) => {
          useEffect(() => {
            fetchUser();
          }, [fetchUser]);
        
          if (user.loading) {
            return <div>Loading...</div>;
          }
        
          if (user.error) {
            return <div>Error: {user.error}</div>;
          }
        
          return (
            <div>
              <h1>User: {user.name}</h1>
              <p>Email: {user.email}</p>
            </div>
          );
        };
        
        const mapStateToProps = state => {
          return {
            user: state.user
          };
        };
        
        export default connect(mapStateToProps, { fetchUser })(UserComponent);
        

        在上面的示例中,我们使用connect函数将Redux存储中的user状态映射为组件的属性。我们还将fetchUser异步动作创建函数映射为组件的属性。在组件加载时,我们使用useEffect钩子调用fetchUser函数来发起异步操作。

      • 这样,你就可以使用Redux Thunk中间件来处理异步操作了。当调用异步动作创建函数时,Redux Thunk会将函数作为参数传递给dispatch方法,并在适当的时候派发动作。在异步操作完成后,你可以在归约器中处理相应的动作来更新状态。

  • Redux Saga

    • 介绍:Redux Saga是一个用于处理复杂的异步操作和副作用的中间件。它使用了ES6的Generator函数来实现异步流控制。Redux Saga提供了一种声明式的方式来管理副作用,通过监听和响应动作来触发异步操作。它可以用于处理异步请求、定时任务、WebSocket通信等。
    • 使用:

    • 安装:

      npm install redux redux-saga --save
      
    • 在创建Redux存储(store)之前,需要将Redux Saga中间件应用到Redux存储中。在创建存储之前,通过applyMiddleware方法将Redux Saga中间件传递给createStore函数。例如:

      import { createStore, applyMiddleware } from 'redux';
      import createSagaMiddleware from 'redux-saga';
      import rootReducer from './reducers';
      import rootSaga from './sagas';
      
      const sagaMiddleware = createSagaMiddleware();
      const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));
      
      sagaMiddleware.run(rootSaga);
      

      在上面的示例中,我们首先创建了一个Redux Saga中间件实例sagaMiddleware。然后,将其作为参数传递给applyMiddleware函数,并将其作为第二个参数传递给createStore函数。最后,我们使用sagaMiddleware.run方法来运行根Saga。

    • 这样,你就可以使用Redux Saga来处理复杂的异步操作和副作用了。当调用Saga函数时,Redux Saga会自动监听相应的动作,并在适当的时候执行相应的处理逻辑。在处理逻辑中,你可以使用Saga提供的效果函数来处理异步操作、派发动作和控制流程。

    • 创建Saga文件。在Redux Saga中,我们需要创建一个或多个Saga文件来处理异步操作和副作用。Saga文件通常包含一个或多个Generator函数,这些Generator函数被称为Saga。例如,我们创建一个名为userSaga.js的Saga文件来处理用户相关的异步操作:

      import { call, put, takeEvery } from 'redux-saga/effects';
      import { FETCH_USER_REQUEST, fetchUserSuccess, fetchUserFailure } from './actions';
      import api from './api';
      
      function* fetchUser() {
        try {
          const user = yield call(api.fetchUser);
          yield put(fetchUserSuccess(user));
        } catch (error) {
          yield put(fetchUserFailure(error.message));
        }
      }
      
      function* userSaga() {
        yield takeEvery(FETCH_USER_REQUEST, fetchUser);
      }
      
      export default userSaga;
      

      在上面的示例中,我们定义了一个fetchUser的Saga函数。在这个Saga函数中,我们使用call效果调用api.fetchUser方法来获取用户数据。然后,使用put效果派发相应的动作,例如fetchUserSuccessfetchUserFailure。最后,我们定义了一个userSaga根Saga函数,使用takeEvery效果监听FETCH_USER_REQUEST动作,并在收到该动作时调用fetchUser函数。

    • 在根Saga文件中组合Saga。我们需要创建一个根Saga文件,将所有的Saga组合在一起。例如,我们创建一个名为rootSaga.js的根Saga文件:

      import { all } from 'redux-saga/effects';
      import userSaga from './userSaga';
      import postSaga from './postSaga';
      
      function* rootSaga() {
        yield all([
          userSaga(),
          postSaga(),
        ]);
      }
      
      export default rootSaga;
      

      在上面的示例中,我们使用all效果将多个Saga函数组合在一起,然后将其导出为根Saga函数。

    • 在组件中使用Saga。你可以在组件中使用connect函数来连接Redux存储,并在组件加载时调用Saga函数。例如:

      import React, { useEffect } from 'react';
      import { connect } from 'react-redux';
      import { fetchUserRequest } from './actions';
      
      const UserComponent = ({ user, fetchUserRequest }) => {
        useEffect(() => {
          fetchUserRequest();
        }, [fetchUserRequest]);
      
        if (user.loading) {
          return <div>Loading...</div>;
        }
      
        if (user.error) {
          return <div>Error: {user.error}</div>;
        }
      
        return (
          <div>
            <h1>User: {user.name}</h1>
            <p>Email: {user.email}</p>
          </div>
        );
      };
      
      const mapStateToProps = state => {
        return {
          user: state.user
        };
      };
      
      export default connect(mapStateToProps, { fetchUserRequest })(UserComponent);
      

      在上面的示例中,我们使用connect函数将Redux存储中的user状态映射为组件的属性。我们还将fetchUserRequest动作创建函数映射为组件的属性。在组件加载时,我们使用useEffect钩子调用fetchUserRequest函数来发起异步操作。

  • Redux Observable

    • 介绍:Redux Observable是一个基于RxJS的中间件,用于处理基于事件流的异步操作。它使用Observables来管理异步流,可以处理复杂的异步操作和事件处理逻辑。Redux Observable提供了一种响应式编程的方式来处理副作用,使得在Redux中处理异步操作变得更加灵活和可组合。
    • 使用:
    • 安装:

      npm install redux redux-observable rxjs --save
      
    • 在创建Redux存储(store)之前,需要将Redux Observable中间件应用到Redux存储中。在创建存储之前,通过applyMiddleware方法将Redux Observable中间件传递给createStore函数。例如:

      import { createStore, applyMiddleware } from 'redux';
      import { createEpicMiddleware } from 'redux-observable';
      import { rootEpic } from './epics';
      import rootReducer from './reducers';
      
      const epicMiddleware = createEpicMiddleware();
      const store = createStore(rootReducer, applyMiddleware(epicMiddleware));
      
      epicMiddleware.run(rootEpic);
      

      在上面的示例中,我们首先创建了一个Redux Observable中间件实例epicMiddleware。然后,将其作为参数传递给applyMiddleware函数,并将其作为第二个参数传递给createStore函数。最后,我们使用epicMiddleware.run方法来运行根Epic。

    • 创建Epic文件。在Redux Observable中,我们需要创建一个或多个Epic文件来处理异步操作和副作用。Epic是一个函数,它接收一个Observable输入流,处理输入流中的动作,并返回一个输出流,该输出流也是一个Observable。例如,我们创建一个名为userEpic.js的Epic文件来处理用户相关的异步操作:

      import { ofType } from 'redux-observable';
      import { mergeMap, map, catchError } from 'rxjs/operators';
      import { FETCH_USER_REQUEST, fetchUserSuccess, fetchUserFailure } from './actions';
      import api from './api';
      
      export const fetchUserEpic = action$ =>
        action$.pipe(
          ofType(FETCH_USER_REQUEST),
          mergeMap(action =>
            api.fetchUser().pipe(
              map(user => fetchUserSuccess(user)),
              catchError(error => {
                console.error(error);
                return fetchUserFailure(error.message);
              })
            )
          )
        );
      

      在上面的示例中,我们定义了一个fetchUserEpic函数。在这个函数中,我们使用ofType操作符来过滤输入流中与FETCH_USER_REQUEST动作类型匹配的动作。然后,使用mergeMap操作符来处理输入流中的动作,并通过调用api.fetchUser方法来获取用户数据。通过使用map操作符,我们将获取到的用户数据转换为fetchUserSuccess动作。如果在获取用户数据时出现错误,我们使用catchError操作符来捕获错误,并返回fetchUserFailure动作。

    • 在根Epic文件中组合Epic。我们需要创建一个根Epic文件,将所有的Epic组合在一起。例如,我们创建一个名为rootEpic.js的根Epic文件:

      import { combineEpics } from 'redux-observable';
      import { fetchUserEpic } from './userEpic';
      import { fetchPostEpic } from './postEpic';
      
      export const rootEpic = combineEpics(fetchUserEpic, fetchPostEpic);
      

      在上面的示例中,我们使用combineEpics函数将多个Epic函数组合在一起,并将其导出为根Epic函数。

    • 在组件中使用Epic。你可以在组件中使用connect函数来连接Redux存储,并在组件加载时调用Epic函数。例如:

      import React, { useEffect } from 'react';
      import { connect } from 'react-redux';
      import { fetchUserRequest } from './actions';
      
      const UserComponent = ({ user, fetchUserRequest }) => {
        useEffect(() => {
          fetchUserRequest();
        }, [fetchUserRequest]);
      
        if (user.loading) {
          return <div>Loading...</div>;
        }
      
        if (user.error) {
          return <div>Error: {user.error}</div>;
        }
      
        return (
          <div>
            <h1>User: {user.name}</h1>
            <p>Email: {user.email}</p>
          </div>
        );
      };
      
      const mapStateToProps = state => {
        return {
          user: state.user
        };
      };
      
      export default connect(mapStateToProps, { fetchUserRequest })(UserComponent);
      

      在上面的示例中,我们使用connect函数将Redux存储中的user状态映射为组件的属性。我们还将fetchUserRequest动作创建函数映射为组件的属性。在组件加载时,我们使用useEffect钩子调用fetchUserRequest函数来发起异步操作。

    • 这样,你就可以使用Redux Observable来处理复杂的异步操作和副作用了。当调用Epic函数时,Redux Observable会自动监听相应的

  • Redux Promise

    • 介绍:Redux Promise是一个用于处理Promise的中间件。它允许在动作创建函数中返回一个Promise对象,该Promise对象可以用于处理异步操作。当Promise对象被解析时,Redux Promise会派发一个带有解析值的新动作。
    • 使用:
    • 首先,确保你的应用已经安装了redux和redux-promise库。可以使用以下命令进行安装:

      npm install redux redux-promise --save
      
    • 在创建Redux存储(store)之前,需要将Redux Promise中间件应用到Redux存储中。在创建存储之前,通过applyMiddleware方法将Redux Promise中间件传递给createStore函数。例如:

      import { createStore, applyMiddleware } from 'redux';
      import promiseMiddleware from 'redux-promise';
      import rootReducer from './reducers';
      
      const store = createStore(rootReducer, applyMiddleware(promiseMiddleware));
      

      在上面的示例中,我们通过applyMiddleware方法将Redux Promise中间件传递给createStore函数,以便在创建存储时应用该中间件。

    • 创建Action。在Redux Promise中,我们可以使用Promise对象作为Action的payload。当使用Redux Promise中间件时,它会自动处理Promise对象并根据Promise的状态分发相应的Action。例如,我们创建一个名为fetchUser的Action来获取用户数据:

      export const fetchUser = () => ({
        type: 'FETCH_USER',
        payload: api.fetchUser() // 返回一个Promise对象
      });
      

      在上面的示例中,我们通过调用api.fetchUser方法来获取用户数据,并将返回的Promise对象作为Action的payload。

    • 创建Reducer。在Reducer中,我们可以使用Redux Promise中间件处理Promise对象的状态,并更新状态。例如,我们可以创建一个名为userReducer的Reducer来处理用户数据:

      const initialState = {
        user: null,
        loading: false,
        error: null
      };
      
      const userReducer = (state = initialState, action) => {
        switch (action.type) {
          case 'FETCH_USER_PENDING':
            return {
              ...state,
              loading: true,
              error: null
            };
          case 'FETCH_USER_FULFILLED':
            return {
              ...state,
              loading: false,
              user: action.payload
            };
          case 'FETCH_USER_REJECTED':
            return {
              ...state,
              loading: false,
              error: action.payload
            };
          default:
            return state;
        }
      };
      

      在上面的示例中,我们定义了一个userReducer函数,它根据不同的Action类型更新用户状态。当FETCH_USER_PENDING动作被分发时,我们将loading状态设置为true,并将error状态设置为null。当FETCH_USER_FULFILLED动作被分发时,我们将loading状态设置为false,并将user状态更新为Action的payload。当FETCH_USER_REJECTED动作被分发时,我们将loading状态设置为false,并将error状态更新为Action的payload。

    • 在组件中使用Action。你可以在组件中使用connect函数来连接Redux存储,并在组件中调用Action函数。当Action函数被调用时,Redux Promise中间件会自动处理Promise对象的状态,并分发相应的Action。例如:

      import React, { useEffect } from 'react';
      import { connect } from 'react-redux';
      import { fetchUser } from './actions';
      
      const UserComponent = ({ user, fetchUser }) => {
        useEffect(() => {
          fetchUser();
        }, [fetchUser]);
      
        if (user.loading) {
          return <div>Loading...</div>;
        }
      
        if (user.error) {
          return <div>Error: {user.error}</div>;
        }
      
        return (
          <div>
            <h1>User: {user.name}</h1>
            <p>Email: {user.email}</p>
          </div>
        );
      };
      
      const mapStateToProps = state => {
        return {
          user: state.user
        };
      };
      
      export default connect(mapStateToProps, { fetchUser })(UserComponent);
      

      在上面的示例中,我们使用connect函数将Redux存储中的user状态映射为组件的属性。我们还将fetchUserAction创建函数映射为组件的属性。在组件加载时,我们使用useEffect钩子调用fetchUser函数来发起异步操作。

    • 这样,你就可以使用Redux Promise来简化处理异步操作的流程了。当调用Action函数时,Redux Promise中间件会自动处理Promise对象的状态,并根据Promise的状态分发相应的Action。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redux中,常用的中间件redux-thunk、redux-saga和redux-logger。redux-thunk的主要作用是可以使action可以变成函数形式,接收两个参数dispatch和getState,可以进行异步操作。redux-saga是一个强大的异步处理库,它使用了ES6的Generator函数来处理异步流程,可以更加清晰和可控地管理副作用。redux-logger的主要作用是在控制台打印输出新老state等信息,方便开发调试。这些中间件在开发过程中可以提高代码的可读性和可维护性,使开发者更方便地处理异步操作和调试程序。此外,react-reduxRedux官方提供的用于配合React的绑定库,它提供了Provider和connect这两个重要的成员,可以更方便地在React组件中使用Redux的状态和操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【面试题】redux中间件相关面试题&解析](https://blog.csdn.net/Ronychen/article/details/125679270)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [React,Redix面试题](https://blog.csdn.net/qq_48962360/article/details/127098928)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值