redux-saga调用API传参出现404错误,如何正确传参并将数据存入store?
问题根因
- 核心问题是Action类型复用冲突:你用来触发API请求、存储请求结果的Action用了同一个
GET_POST类型。当请求成功后执行yield put(getPost(data))时,会再次被sagas.js里的takeLatest(GET_POST, handleGetPost)监听到,二次执行请求逻辑。此时传入的action.id是接口返回的帖子对象,拼接到URL后就会被转为[object Object],直接触发404报错。 - 附带问题是Reducer逻辑错误:当前Reducer收到
GET_POSTAction时,直接把action.id赋值给post字段,完全没有区分action.id是用户输入的查询ID还是接口返回的帖子数据,存储逻辑混乱。
修复方案
需要拆分Action类型,区分「触发查询请求」和「请求成功存储数据」两个场景,修改涉及三个文件:
1. 修改getPost.js
新增请求成功的Action类型和对应Action生成函数,调整Reducer存储逻辑:
const GET_POST = 'GET_POST'; // 新增:请求成功的Action类型 const GET_POST_SUCCESS = 'GET_POST_SUCCESS'; const initialState = { post: '', }; // 原Action不变:用来触发查询请求,传入用户输入的ID const getPost = (id) => ({ type: GET_POST, id, }); // 新增:请求成功的Action,传入接口返回的帖子数据 const getPostSuccess = (postData) => ({ type: GET_POST_SUCCESS, payload: postData }); const fetchPostReducer = (state = initialState, action) => { switch (action.type) { // 仅处理请求成功的Action,存储帖子数据到store case GET_POST_SUCCESS: return { ...state, post: action.payload }; default: return state; } }; export { getPost, getPostSuccess, GET_POST, GET_POST_SUCCESS }; export default fetchPostReducer;
2. 修改sagas.js
请求成功后触发新增的成功Action,避免循环触发请求:
import { getPostSuccess, GET_POST } from './getPost'; export function requestGetPost(id) { return axios.request({ method: 'get', url: `https://jsonplaceholder.typicode.com/posts/${id}`, }); } function* handleGetPost(action) { try { const response = yield call(requestGetPost, action.id); const { data } = response; // 修改为触发成功Action,传入接口返回的数据 yield put(getPostSuccess(data)); } catch (error) { console.log(error); } } export function* watcherSaga() { yield takeLatest(GET_POST, handleGetPost); }
3. 可选优化FetchPost.js
可以把用户输入的ID转为数字,避免字符串类型的ID带来的潜在问题:
const handleSubmit = (event) => { event.preventDefault(); // 把输入的字符串ID转为数字 dispatch(getPost(Number(idRef.current.value))); };
内容的提问来源于stack exchange,提问作者FST
相关产品推荐
相关产品推荐

