首页 > 解决方案 > Redux:如何仅在 useEffect 中分派操作一次?

问题描述

我有一个日历应用程序,用户可以在其中为每个日历页面上传 1-4 张图像。

预期结果: 当用户上传质量不佳的图像时,我会收到一个质量警告 toast,每个图像都应该出现一次。

当前结果: 现在 中的操作showToastuseEffect多次触发。因此,例如,当我上传新图像、删除另一个图像等时,每次再次触发此质量警告。

我的方法: 我尝试实现本地状态以切换布尔值(如果警告显示一次,则设置为 false)。但我只能让它适用于所有图像(只要任何图像质量不好,本地状态就会设置为 false)。但我需要它是特定于图像的。

如果特定图像的质量警告已显示,则不再显示。

代码:

export const useShowPoorImageQualityToast = (spreadId: string): void => {
    const dispatch = useDispatch();

    const [qualityToastIsShown, setQualityToastWasShown] = useState(false); // my approach

    const poorQualityContentIds = useSelector(
        (state: AppState) =>
            spreadWithImageContentsSelector(state, spreadId).filter((contentId) => {
                const qualityInformation = productImageQualitySelector(state, contentId);

                return qualityInformation !== undefined && qualityInformation.hasPoorQuality
            }),
        shallowEqual
    );

    useEffect(() => {
        const imageQualityWarningToast: ClosableToast = {
            mode: ToastMode.CLOSABLE,
            text: locale.photoQualityWarning.toast,
            severity: ToastSeverity.WARN,
            closable: false,
        };

        if (poorQualityContentIds.length > 0 && qualityToastIsShown === false) {

            dispatch(showToast(ToastType.NONE, imageQualityWarningToast));

            setQualityToastWasShown(!qualityToastIsShown); // my approach
        }
    }, [dispatch, poorQualityContentIds, qualityToastIsShown]);
};

标签: reactjsredux

解决方案


我以前研究过这类问题,但我认为这不是最优化的。

所以我所做的不是只存储一个布尔值,而是存储图像 id 或每个图像的一些引用,然后检查存储在该图像 id 中的布尔值。这样,您每次只为一个特定图像设置标志,并且只检查它。

所以,在你的本地状态存储这样的东西:

{
  image1: { warningShown: true },
  image2: { warningShown: false }
}

推荐阅读