Redux 在 React 中将对象数组添加到另一个数组中
Redux Added Array of Object Inside Another Aray in React
我这里的产品可能有一张或多张图片。取决于产品代码。
如果 productCode 是它们属于同一产品。 productCode 可以在图像的文件名中找到,它位于第一个下划线之后。例如,如果文件名是 AA_BB_CC.jpg。 productCode 是 BB.
您可以在我的codesandbox中查看示例图片。
因此,如果图像具有相同的 productCode,它应该加起来就是产品。我的问题在这部分。添加具有相同产品代码的产品图片。
这是codesandbox
CLICK HERE
代码
return {
...state,
products: [...state.products, ...action.payload]
};
预期输出
预期输出的响应
您可以使用 immer
reducer 可以根据“productCode”使用 immer 的 produce 函数将新图像推送到正确的“proudctImages”数组
import produce from 'immer';
...
return {
...state,
products: produce(state.products, draftProducts => {
const product = findProductWithProductCode(draftProducts, action.payload.productCode);
product.productImages.push(...action.payload.productImages)
})
};
您还需要新图像的产品代码信息。
"findProductWithProductCode" 只是遍历 draftProducts 并找到 "productCode" = action.payload.productCode
的数组元素
我看到您在创建文件图像对象时已经在文件上传器中进行了字符串拆分。在这种情况下,您只需要检查生成的 productCode
图像对象负载,看看它是否已包含在 products
数组中。如果不是,则生成新的“产品”状态对象并将图像添加到数组,否则将不可变更新模式应用于浅拷贝状态并附加新文件对象。
由于操作负载中的每个产品可能属于不同的产品,因此您需要迭代此数组以确定应合并每个新产品的位置。
case appConstants.UPLOAD_PRODUCT_SUCCESS:
// (1) iterate the product images array
return action.payload.reduce(
(
state,
{
productCode,
productName,
productCategory,
imageFile,
imageFileName
}
) => {
// (2) Check if the product is already in state
const shouldUpdate = state.products.some(
(product) => product.productCode === productCode
);
// (3a) If we just need to return updated state with added new image
if (shouldUpdate) {
return {
...state,
// (4) shallow copy the products array
products: state.products.map((product) =>
product.productCode === productCode
// (4b) If this is the matching product, shallow copy product
// append a new image file object with new id
? {
...product,
productImages: product.productImages.concat({
id: uuidV4(),
imageFile,
imageFileName
})
}
// (4b) copy forward existing product object
: product
)
};
}
// (3b) Create a new product object and initially populate images array
return {
...state,
products: state.products.concat({
productCode,
productName,
productCategory,
productExisting: true,
productImages: [
{
id: uuidV4(),
imageFile,
imageFileName
}
]
})
};
},
state
);
我这里的产品可能有一张或多张图片。取决于产品代码。 如果 productCode 是它们属于同一产品。 productCode 可以在图像的文件名中找到,它位于第一个下划线之后。例如,如果文件名是 AA_BB_CC.jpg。 productCode 是 BB.
您可以在我的codesandbox中查看示例图片。
因此,如果图像具有相同的 productCode,它应该加起来就是产品。我的问题在这部分。添加具有相同产品代码的产品图片。
这是codesandbox CLICK HERE
代码
return {
...state,
products: [...state.products, ...action.payload]
};
预期输出
预期输出的响应
您可以使用 immer
reducer 可以根据“productCode”使用 immer 的 produce 函数将新图像推送到正确的“proudctImages”数组
import produce from 'immer';
...
return {
...state,
products: produce(state.products, draftProducts => {
const product = findProductWithProductCode(draftProducts, action.payload.productCode);
product.productImages.push(...action.payload.productImages)
})
};
您还需要新图像的产品代码信息。
"findProductWithProductCode" 只是遍历 draftProducts 并找到 "productCode" = action.payload.productCode
的数组元素我看到您在创建文件图像对象时已经在文件上传器中进行了字符串拆分。在这种情况下,您只需要检查生成的 productCode
图像对象负载,看看它是否已包含在 products
数组中。如果不是,则生成新的“产品”状态对象并将图像添加到数组,否则将不可变更新模式应用于浅拷贝状态并附加新文件对象。
由于操作负载中的每个产品可能属于不同的产品,因此您需要迭代此数组以确定应合并每个新产品的位置。
case appConstants.UPLOAD_PRODUCT_SUCCESS:
// (1) iterate the product images array
return action.payload.reduce(
(
state,
{
productCode,
productName,
productCategory,
imageFile,
imageFileName
}
) => {
// (2) Check if the product is already in state
const shouldUpdate = state.products.some(
(product) => product.productCode === productCode
);
// (3a) If we just need to return updated state with added new image
if (shouldUpdate) {
return {
...state,
// (4) shallow copy the products array
products: state.products.map((product) =>
product.productCode === productCode
// (4b) If this is the matching product, shallow copy product
// append a new image file object with new id
? {
...product,
productImages: product.productImages.concat({
id: uuidV4(),
imageFile,
imageFileName
})
}
// (4b) copy forward existing product object
: product
)
};
}
// (3b) Create a new product object and initially populate images array
return {
...state,
products: state.products.concat({
productCode,
productName,
productCategory,
productExisting: true,
productImages: [
{
id: uuidV4(),
imageFile,
imageFileName
}
]
})
};
},
state
);