Redux 传奇:我需要将参数传递给 axios

Redux saga: I need to pass argument to axios

由于我公司的要求,我正在将我的代码从 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

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

因此,如果您在原始 JS 代码中有此内容:

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

在传奇中会是这样:

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

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

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',
    });
  }
}