api调用useEffect中的延迟状态更新

时间:2020-09-12 09:47:44

标签: reactjs setstate use-effect

我遇到一个问题,即垃圾邮件2个按钮无法正确更新状态。

export default function App() {
    const [items, setItems] = useState(null);
    const [showCustom, setShowCustom] = useState(false);
    const customItems = useSelector(flipBoardItems);
    const dispatch = useDispatch();

    useEffect(() => {
        (async () => {
            if (!showCustom) {
                const data = await getFlipBoardContent();
                setItems(() => data);
            } else {
                setItems(() => Object.values(customItems));
            }
        })();
    }, [customItems, showCustom]);

    return (
        <div>
            <Paper>
                <Toolbar>
                    <Button onClick={() => setShowCustom(true)}>Show Custom</Button>
                    <Button onClick={() => setShowCustom(false)}>Show Live</Button>
                </Toolbar>
            </Paper>
                </div>
         );

问题是,如果我将showCustom从true切换为false,它将启动api调用,但是如果我将它迅速切换回true,则将完成api并将项目设置为活动状态,因为在那时,custom是错误的,甚至以后我的showCustom也是如此。

我已经看到多个有关如何在卸载组件时执行此操作的示例,但是找不到与我的问题有关的任何内容。

我的问题是,当showCustom为true时,如何防止useEffect api调用更新项目状态?

1 个答案:

答案 0 :(得分:0)

您可以执行类似于卸载组件时取消的操作:

    useEffect(() => {
        let fetchCanceled = false;

        (async () => {
            if (!showCustom) {
                const data = await getFlipBoardContent();

                if (fetchCanceled) {
                  return;
                }

                setItems(data);
            } else {
                setItems(Object.values(customItems));
            }
        })();

        return () => {
          fetchCanceled = true;
        };
    }, [customItems, showCustom]);

只要useEffect的值发生更改,就会调用showCustom的返回函数,因此,如果在开始获取数据后单击showCustom,它将在之前fetchCanceled翻转为true设置数据。

此外:除非您使用setItems的当前值来更新该值,否则不需要items的功能形式。