React 中的 Redux 调用多个调度函数 [英] Redux in React to call multiple dispatch functions

查看:30
本文介绍了React 中的 Redux 调用多个调度函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个调用动作的 index.js.一旦它调用一个动作,我想在该动作中触发多个调度动作.Index.js 调用 handLoadCustomers,后者将调度 loadCustomers 函数,该函数调用 API 并调度另一个函数以将客户存储在状态中.

一旦完成,调用返回到 handleLoadCustomers,我想从第一个开始使用客户调用,然后将 handleExtraCustomerLoads 的另一个动作发送给那些将调用另一个函数/动作.我如何在 React Redux 中做到这一点?

导出函数handleLoadCustomers() {返回函数(调度){调度(加载客户()).then((客户) => {dispatch(handleExtraCustomerLoads(customers));}).catch((错误) => {抛出错误;}).then((newCustomers) => {dispatch(handlePageLoadSuccess(newCustomers));});};导出函数 loadCustomers() {返回函数(调度){返回 getCustomers().then((客户) => {dispatch(loadCustomerSuccess(customers));}).catch((错误) => {抛出错误;});};}

loadCustomers 之后的customers 为空,并且根本不分派handleExtraCustomerLoads 函数

解决方案

你不应该使用你的动作的返回值,但你可以等待它完成并从状态中选择结果(我假设动作会写数据你需要去商店).

const { Provider, useDispatch, useSelector } = ReactRedux;const { createStore, applyMiddleware, compose } = Redux;常量初始状态 = {顾客: [],额外的: [],};//APIconst getCustomers = () =>Promise.resolve([1, 2, 3]);//动作类型const CUSTOMERS_SUCCESS = 'CUSTOMERS_SUCCESS';const 额外 = '额外';//动作创建者const loadCustomerSuccess = (客户) =>({类型:客户成功,有效载荷:客户,});const handleExtraCustomerLoads = (额外) =>({类型:额外,有效载荷:额外的,});函数 handleLoadCustomers() {返回函数(调度,getState){dispatch(loadCustomers()).then(() => {const 客户 = selectCustomers(getState());dispatch(handleExtraCustomerLoads(customers));});};}函数加载客户(){返回函数(调度){返回 getCustomers().then((客户) => {//你需要在这里返回值返回调度(加载客户成功(客户));}).catch((错误) => {抛出错误;});};}const reducer = (state, { type, payload }) =>{如果(类型 === CUSTOMERS_SUCCESS){返回 { ...状态,客户:有效载荷 };}如果(类型 === 额外){返回 { ...状态,额外:有效载荷 };}返回状态;};//选择器const selectCustomers = (state) =>状态.客户;const selectExtra = (状态) =>状态.额外;//使用 redux 开发工具创建 storeconst composeEnhancers =窗口.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ||撰写;const store = createStore(减速器,初始状态,composeEnhancers(applyMiddleware((store) => (next) => (action) =>//diy thunktypeof action === '函数'?动作(store.dispatch,store.getState):下一步(行动))));const App = () =>{const dispatch = useDispatch();const 客户 = useSelector(selectCustomers);const extra = useSelector(selectExtra);返回 (<div><按钮onClick={() =>dispatch(handleLoadCustomers())}>加载客户<预>{JSON.stringify({客户,额外},未定义,2)}

);};ReactDOM.render(<提供者商店={商店}><应用程序/></提供者>,document.getElementById('root'));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script><div id="root"></div>

I have an index.js which calls an action. Once it calls an action I want to trigger multiple dispatch actions inside that action. Index.js calls handLoadCustomers which will dispatch loadCustomers function which calls an API and dispatches another function to store customers in the state.

Once that is done, call comes back to handleLoadCustomers where I want to use customers from the first call and then dispatch another action of handleExtraCustomerLoads with those customers which will call another functions/actions. How can I do that in React Redux?

export function handleLoadCustomers() {
  return function (dispatch) {
    dispatch(loadCustomers())
      .then((customers) => {
        dispatch(handleExtraCustomerLoads(customers));
      })
      .catch((error) => {
        throw error;
      })
      .then((newCustomers) => {
        dispatch(handlePageLoadSuccess(newCustomers));
      });
  };



export function loadCustomers() {
  return function (dispatch) {
    return getCustomers()
      .then((customers) => {
        dispatch(loadCustomerSuccess(customers));
      })
      .catch((error) => {
        throw error;
      });
  };
}


customers after the loadCustomers is empty and it does not dispatch handleExtraCustomerLoads function at all

解决方案

You should not use the return value of your action but you can wait for it to finish and select the result from the state (I assume the action will write data you need to the store).

const { Provider, useDispatch, useSelector } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;

const initialState = {
  customers: [],
  extra: [],
};
//api
const getCustomers = () => Promise.resolve([1, 2, 3]);
//action types
const CUSTOMERS_SUCCESS = 'CUSTOMERS_SUCCESS';
const EXTRA = 'EXTRA';
//action creators
const loadCustomerSuccess = (customers) => ({
  type: CUSTOMERS_SUCCESS,
  payload: customers,
});
const handleExtraCustomerLoads = (extra) => ({
  type: EXTRA,
  payload: extra,
});
function handleLoadCustomers() {
  return function (dispatch, getState) {
    dispatch(loadCustomers()).then(() => {
      const customers = selectCustomers(getState());
      dispatch(handleExtraCustomerLoads(customers));
    });
  };
}
function loadCustomers() {
  return function (dispatch) {
    return getCustomers()
      .then((customers) => {
        //you need to return the value here
        return dispatch(loadCustomerSuccess(customers));
      })
      .catch((error) => {
        throw error;
      });
  };
}

const reducer = (state, { type, payload }) => {
  if (type === CUSTOMERS_SUCCESS) {
    return { ...state, customers: payload };
  }
  if (type === EXTRA) {
    return { ...state, extra: payload };
  }
  return state;
};
//selectors
const selectCustomers = (state) => state.customers;
const selectExtra = (state) => state.extra;
//creating store with redux dev tools
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,
  initialState,
  composeEnhancers(
    applyMiddleware((store) => (next) => (action) =>
      //diy thunk
      typeof action === 'function'
        ? action(store.dispatch, store.getState)
        : next(action)
    )
  )
);
const App = () => {
  const dispatch = useDispatch();
  const customers = useSelector(selectCustomers);
  const extra = useSelector(selectExtra);
  return (
    <div>
      <button
        onClick={() => dispatch(handleLoadCustomers())}
      >
        load customers
      </button>
      <pre>
        {JSON.stringify({ customers, extra }, undefined, 2)}
      </pre>
    </div>
  );
};

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>

这篇关于React 中的 Redux 调用多个调度函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆