在 Redux 和 React 中删除时禁用按钮
Disable Button When Deleting in Redux and React
我在删除时禁用按钮时遇到问题。
现在,它禁用所有图像的所有“删除”按钮。
我只想禁用当前正在删除的图像的“删除”。|
因此它将防止在它仍在处理时一次又一次地删除它。
Codesandbox CLICK HERE
<CardActions>
<Button
disabled={isDeletingImages}
variant="contained"
size="medium"
color="primary"
type="button"
onClick={() => confirmDeleteProductImage(productType?.imageFileName)}
>
Delete
</Button>
</CardActions>
您有一个单一的 isDeletingImages
布尔状态,用于所有删除按钮的 disabled
属性。
我建议转换为 Map/Object 个当前正在删除的 ID,并通过 ID 检查当前呈现的项目的删除按钮是否正在被删除。
更新 deleteProductImage
动作创建者以分派 DELETE_PRODUCT_IMAGE_REQUEST
和 DELETE_PRODUCT_IMAGE_FAILURE
动作类型,当前 imageFileName
为 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
});
}
};
更新 productReducer
以使用对象而不是布尔值。
export const initialState = {
products: [],
errors: [],
isDeletingImages: {} // <-- object to hold file names
};
通过文件名将 DELETE_PRODUCT_IMAGE_REQUEST
、DELETE_PRODUCT_IMAGE_SUCCESS
和 DELETE_PRODUCT_IMAGE_FAILURE
减速器案例更新为 set/clear 当前删除状态。
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
}
};
更新删除按钮以检查 isDeletingImages
状态及其当前 imageFileName
值。
<Button
disabled={isDeletingImages[productType.imageFileName]}
variant="contained"
size="medium"
color="primary"
type="button"
onClick={() => confirmDeleteProductImage(productType?.imageFileName)}
>
Delete
</Button>
当 DELETE_PRODUCT_IMAGE_REQUEST
被分派时,您可以将图像文件名作为附加负载添加到操作中(我假设文件名唯一标识要删除的内容)。
在 reducer 中,从操作负载中读取图像文件名并改变状态,以反映哪些特定图像正在被删除。例如,一个包含图像文件名作为键和 true
作为值的对象。
export const initialState = {
products: [],
errors: [],
imagesInDeletion: {
// example entry: 'nameofimage.jpg': true,
},
};
imagesInDeletion
现在会告诉您哪个图像正在被删除。你可以根据它写一个选择器,比如isImageBeingDeleted('nameofimage.jpg')
,让它return true
或者false
。然后,选择器可用于按钮的 disabled
属性。
此外,reducer 还需要做一些工作才能正确更新此状态。如果图像已成功删除,则应将其从 imagesInDeletion
中删除,例如。
这是解决此问题的一种可能方法,但问题的核心是您需要为每个 product/image 跟踪图像删除生命周期的更详细状态。有时候re-modelling状态方便一点,也不失为一个好办法。
我在删除时禁用按钮时遇到问题。 现在,它禁用所有图像的所有“删除”按钮。 我只想禁用当前正在删除的图像的“删除”。| 因此它将防止在它仍在处理时一次又一次地删除它。
Codesandbox CLICK HERE
<CardActions>
<Button
disabled={isDeletingImages}
variant="contained"
size="medium"
color="primary"
type="button"
onClick={() => confirmDeleteProductImage(productType?.imageFileName)}
>
Delete
</Button>
</CardActions>
您有一个单一的 isDeletingImages
布尔状态,用于所有删除按钮的 disabled
属性。
我建议转换为 Map/Object 个当前正在删除的 ID,并通过 ID 检查当前呈现的项目的删除按钮是否正在被删除。
更新
deleteProductImage
动作创建者以分派DELETE_PRODUCT_IMAGE_REQUEST
和DELETE_PRODUCT_IMAGE_FAILURE
动作类型,当前imageFileName
为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 }); } };
更新
productReducer
以使用对象而不是布尔值。export const initialState = { products: [], errors: [], isDeletingImages: {} // <-- object to hold file names };
通过文件名将
DELETE_PRODUCT_IMAGE_REQUEST
、DELETE_PRODUCT_IMAGE_SUCCESS
和DELETE_PRODUCT_IMAGE_FAILURE
减速器案例更新为 set/clear 当前删除状态。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 } };
更新删除按钮以检查
isDeletingImages
状态及其当前imageFileName
值。<Button disabled={isDeletingImages[productType.imageFileName]} variant="contained" size="medium" color="primary" type="button" onClick={() => confirmDeleteProductImage(productType?.imageFileName)} > Delete </Button>
当 DELETE_PRODUCT_IMAGE_REQUEST
被分派时,您可以将图像文件名作为附加负载添加到操作中(我假设文件名唯一标识要删除的内容)。
在 reducer 中,从操作负载中读取图像文件名并改变状态,以反映哪些特定图像正在被删除。例如,一个包含图像文件名作为键和 true
作为值的对象。
export const initialState = {
products: [],
errors: [],
imagesInDeletion: {
// example entry: 'nameofimage.jpg': true,
},
};
imagesInDeletion
现在会告诉您哪个图像正在被删除。你可以根据它写一个选择器,比如isImageBeingDeleted('nameofimage.jpg')
,让它return true
或者false
。然后,选择器可用于按钮的 disabled
属性。
此外,reducer 还需要做一些工作才能正确更新此状态。如果图像已成功删除,则应将其从 imagesInDeletion
中删除,例如。
这是解决此问题的一种可能方法,但问题的核心是您需要为每个 product/image 跟踪图像删除生命周期的更详细状态。有时候re-modelling状态方便一点,也不失为一个好办法。