I have here a problem disabling the button when deleting. Right now, it disables all the "Delete" Button of all images. I only wanted to disable the "Delete" of the currently deleting image.| So it it will prevent from deleting it again and again while it is still processing.
Codesandbox CLICK HERE
<CardActions>
<Button
disabled={isDeletingImages}
variant="contained"
size="medium"
color="primary"
type="button"
onClick={() => confirmDeleteProductImage(productType?.imageFileName)}
>
Delete
</Button>
</CardActions>
You have a single isDeletingImages
boolean state that you are using for all delete button's disabled
prop.
I suggest converting to a Map/Object of ids that are currently being deleted, and checking by id if the delete button for the currently rendered item is currently being deleted.
Update the deleteProductImage
action creator to dispatch the DELETE_PRODUCT_IMAGE_REQUEST
and DELETE_PRODUCT_IMAGE_FAILURE
action types with the current imageFileName
as payload
.
export const deleteProductImage = ({
productIndex,
imageFileName,
callback = () => {}
}) => async (dispatch) => {
try {
dispatch({
type: appConstants.DELETE_PRODUCT_IMAGE_REQUEST,
payload: { productIndex, imageFileName }, // <-- pass payload
});
const response = await axios.get(
"https://jsonplaceholder.typicode.com/todos/1"
);
if (response) {
dispatch({
type: appConstants.DELETE_PRODUCT_IMAGE_SUCCESS,
payload: { productIndex, imageFileName }
});
}
} catch (error) {
dispatch({
type: appConstants.DELETE_PRODUCT_IMAGE_FAILURE,
payload: { productIndex, imageFileName }, // <-- pass payload
});
}
};
Update the productReducer
to use an object instead of a boolean value.
export const initialState = {
products: [],
errors: [],
isDeletingImages: {} // <-- object to hold file names
};
Update the DELETE_PRODUCT_IMAGE_REQUEST
, DELETE_PRODUCT_IMAGE_SUCCESS
, and DELETE_PRODUCT_IMAGE_FAILURE
reducer cases to set/clear the current delete status by the file name.
case appConstants.DELETE_PRODUCT_IMAGE_REQUEST:
return {
...state,
isDeletingImages: {
...state.isDeletingImages,
[action.payload.imageFileName]: true
}
};
case appConstants.DELETE_PRODUCT_IMAGE_SUCCESS:
return {
...state,
isDeletingImages: {
...state.isDeletingImages,
[action.payload.imageFileName]: false
},
products: state?.products.map((item, index) => {
if (index !== action.payload?.productIndex) return item;
return {
...item,
productImages: item?.productImages.filter(
({ imageFileName = null }) =>
imageFileName !== action?.payload?.imageFileName
)
};
})
};
case appConstants.DELETE_PRODUCT_IMAGE_FAILURE:
return {
...state,
isDeletingImages: {
...state.isDeletingImages,
[action.payload.imageFileName]: false
}
};
Update the delete button to check the isDeletingImages
state with its current imageFileName
value.
<Button
disabled={isDeletingImages[productType.imageFileName]}
variant="contained"
size="medium"
color="primary"
type="button"
onClick={() => confirmDeleteProductImage(productType?.imageFileName)}
>
Delete
</Button>