反应异步事件处理程序。安全的方式

React async event handler. The safe way

想象一个简单的 React 组件

const Upload: React.FC = () => {
    const [done, setDone] = useState(false)
    const upload = async () => {
        await doSomeAsyncStuffHere()
        setDone(true)
    }

    if(done) {
        return <div>success</div>
    }

    return (
        <button onClick={upload}>upload</button>
    )
}

乍一看还不错。但是如果上传功能需要很长时间才能完成怎么办?如果用户导航到另一个视图并且组件被卸载怎么办?当异步任务完成时,将导致未安装组件的状态更新。这是一个空操作并且可能是内存泄漏。我应该怎么做才能预防它?

一种解决方法是创建一个 ref 并在卸载组件时将其设置为 false,并在组件中设置异步代码的结果之前对此进行检查状态。

例子

const Upload: React.FC = () => {
    const isMounted = useRef(true);
    const [done, setDone] = useState(false)
    const upload = async () => {
        await doSomeAsyncStuffHere()
        
        if (isMounted.current) {
            setDone(true)
        }
    }

    useEffect(() => {
        return () => {
            isMounted.current = false;
        };
    }, []);

    if(done) {
        return <div>success</div>
    }

    return (
        <button onClick={upload}>upload</button>
    )
}