Redux如何为数组中每个ID分发action,批量获取对应商品对象
实现步骤
1 调整Reducer存储结构
你当前的reducer每次查询都会覆盖单个product对象,无法存储多个商品结果,首先修改存储结构:
const initialState = { // 用对象按ID存储商品,方便快速查找,避免重复 productMap: {}, // 也可以额外存数组,按需选择 productList: [] }; const productReducer = (state = initialState, action) => { switch (action.type) { case GET_PRODUCT_BY_ID: const product = action.payload; return { ...state, productMap: { ...state.productMap, // 以商品ID为key存储,不会覆盖其他商品 [product.id]: product }, // 如果要存数组的话,先判断是否已存在避免重复 productList: state.productList.some(item => item.id === product.id) ? state.productList : [...state.productList, product] }; // 可选:新增批量存储的action类型,一次性存所有结果,性能更好 case GET_PRODUCT_BATCH: const products = action.payload; const newMap = {}; products.forEach(item => newMap[item.id] = item); return { ...state, productMap: {...state.productMap, ...newMap}, productList: [...new Set([...state.productList, ...products])] } default: return state; } };
2 新增批量查询Action
分两种场景,根据后端是否支持批量接口选择:
场景1:后端仅支持单ID查询,前端并行发请求
export const getProductsByIds = (idList) => async(dispatch) => { try { // 并行发起所有请求,比串行效率高 const requestList = idList.map(id => api.getProductById(id)); // 等待所有请求返回,用allSettled可以兼容部分请求失败的场景 const resultList = await Promise.allSettled(requestList); const validProducts = []; resultList.forEach(res => { if (res.status === 'fulfilled') { const product = res.value.data; validProducts.push(product); // 方式1:逐个dispatch复用原有单查逻辑 dispatch({type: GET_PRODUCT_BY_ID, payload: product}); } else { console.error('单个商品查询失败:', res.reason); } }) // 方式2:也可以一次性dispatch批量action,减少渲染次数 // dispatch({type: GET_PRODUCT_BATCH, payload: validProducts}); // 直接返回结果数组,方便调用处直接拿值 return validProducts; } catch (error) { console.log('批量查询失败:', error); return []; } }
场景2:后端支持批量ID查询接口(更推荐,减少请求数)
如果后端有类似api.getProductByIds(idList)的接口,直接调用即可:
export const getProductsByIds = (idList) => async(dispatch) => { try { const {data} = await api.getProductByIds(idList); dispatch({type: GET_PRODUCT_BATCH, payload: data}); return data; } catch (error) { console.log(error); return []; } }
3 调用方法获取结果
需要查询的时候直接传入ID数组即可:
// 示例调用 const idArr = ['16', '149']; // 方式1:调用后直接拿返回的结果数组 const productList = await dispatch(getProductsByIds(idArr)); console.log(productList); // 就是你要的商品对象数组 // 方式2:从redux state中取 // 取数组:state.product.productList // 按ID取单个商品:state.product.productMap['16']
内容的提问来源于stack exchange,提问作者Nedzny
相关产品推荐
相关产品推荐

