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