【问题标题】:Redux saga: I need to pass argument to axiosRedux 传奇:我需要将参数传递给 axios
【发布时间】:2021-03-16 21:05:04
【问题描述】:

由于我公司的要求,我正在将我的代码从 thunk 迁移到 saga。

使用带有参数的 thunk 发送 api 请求非常简单,我很难弄清楚如何将参数传递给 axios 请求

redux/sagas/handlers/marketplace.js

import { call, put, takeLatest } from 'redux-saga/effects';
import {
  FETCH_ALL_ITEMS_FAIL,
  FETCH_ALL_ITEMS_REQUEST,
  FETCH_ALL_ITEMS_SUCCESS,
} from '../../types/marketplaceTypes';
import { fetchAllItemsRequest } from '../requests/marketplace';

export function* fetchAllItems(action) {
  console.log('MARKET PLACE HANDLER', action);
  try {
    const { data } = yield call(fetchAllItemsRequest);
    yield put({
      type: FETCH_ALL_ITEMS_SUCCESS,
      payload: data,
    });
  } catch (error) {
    console.log(error, '<== error while saga');
    yield put({
      type: FETCH_ALL_ITEMS_FAIL,
      error: 'Error loading ITEMS list',
    });
  }
}

export default function* fetchItems() {
  yield takeLatest(FETCH_ALL_ITEMS_REQUEST, fetchAllITEMSs);
}

redux/sagas/requests/marketplace.js

import axios from 'axios';

export const fetchAllApisRequest = (ARGS) => {
  console.log(ARGS);  // Need to pass them from components
  return axios.request({
    method: 'get',
    url: uri,
  });
};

rootSaga.js

import { all } from 'redux-saga/effects';
import { fetchAllItems } from '../sagas/handlers/marketplace';

export function* rootSaga() {
  yield all([fetchAllItems()]);
}

最后,我是如何调度的:

Component.js

useEffect(() => {
  dispatch({
    type: FETCH_ALL_ITEMS_REQUEST,
  })
}, [])  // NOT SURE HOW TO SEND ARGUMENT TO THE AXIOS REQUEST FROM HERE

【问题讨论】:

    标签: javascript reactjs redux react-redux redux-saga


    【解决方案1】:

    正如@markerikson 在他的回答中所说,call 允许您将所需的任何参数传递给被调用的函数。因此,如果每次您想执行此 saga 时都事先知道这些参数,您可以这样做:

    const { data } = yield call(fetchAllItemsRequest, AXIOS_ARGS);
    

    但是您从useEffect 内部的dispatch 调用中询问如何做到这一点,就好像您可能需要使用不同的参数调用相同的saga(通过调度相同的动作类型)。

    在这种情况下,您可以简单地将它们作为“动作负载”的一部分包含在内,因为takeLatest(以及所有类似函数)将整个动作传递给 saga。所以你可以这样做。

    在组件中:

    useEffect(() => {
      dispatch({
        type: FETCH_ALL_ITEMS_REQUEST,
        args: argsINeedForThisRequest
      })
    }, [])
    

    在传奇中 fetchAllItems:

    export function* fetchAllItems(action) {
      console.log('MARKET PLACE HANDLER', action);
      try {
        const { data } = yield call(fetchAllItemsRequest, action.args); // use action payload here
        yield put({
          type: FETCH_ALL_ITEMS_SUCCESS,
          payload: data,
        });
      } catch (error) {
        console.log(error, '<== error while saga');
        yield put({
          type: FETCH_ALL_ITEMS_FAIL,
          error: 'Error loading ITEMS list',
        });
      }
    }
    

    【讨论】:

    • Zigmound,感谢您的详细解释。错误:我在 fetchAllItems 传奇中得到action(被安慰的那个)为undefined
    • @KaranKumar 我注意到您现在已经编辑了您的原始帖子,但我在您编辑之前查看并发现了问题:您将fetchAllItems() 作为第二个参数传递给takeLatest,当它应该只是fetchAlltems。您当前的版本有拼写错误,因此很难看到您当前在做什么,但此更改应该可以解决您提到的 undefined 错误。
    • 是的,另外,我在 rootSaga 中也有错字,我使用的是{ fetchAllItems },而不是导入默认的fetchItems。成功了,非常感谢!!
    【解决方案2】:

    传奇call 效果允许在调用方法之后将函数参数作为附加参数传递。

    所以,如果你在原来的 JS 代码中有这个:

    axios.post('/some/url', data)
    

    这将是一个传奇:

    yield call(axios.post, '/some/url', data)
    

    【讨论】:

    • 谢谢,但我的问题是我如何从消耗参数/参数的Component ===&gt; sagas/requests/marketplace.js 传递
    猜你喜欢
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    相关资源
    最近更新 更多