状态不会使用 React 钩子更新



我以为我明白了钩子中的闭包。但是,我正在为此苦苦挣扎。下面的代码是我用于演示的实际代码的非常简化的版本。实际上,clickHandler()upload()要复杂得多。这就是为什么不能将它们组合成一个函数的原因。问题是我无法从上传函数中的状态访问更新的文件数组。但是,如果我对数组使用 ref 它可以工作,我认为这是一种反模式。我还尝试在组件外部声明状态,但这不起作用。感谢您的帮助。

import React, { useCallback, useState } from 'react';
const HomeScreen = () => {
    const initialState = {
        error: false,
        files: [],
        totalSize: 0,
        finished: false
    };
    const [state, setState] = useState(initialState);
    const upload = useCallback(() => {
        // At this point state.files is an empty array
        console.log(state.files);
    }, [state]);
    const clickHandler = useCallback(() => {
        const queue = [
            { id: 1, bool: false },
            { id: 2, bool: false }
        ];
        setState((state) => {
            return { ...state, files: queue }
        });
        upload()
    }, [upload]);
    return <button onClick={clickHandler}>Click me</button>;
};
export default HomeScreen;

使用 hooks 状态更新程序的状态更新是异步的,因此当您从 clickHandler 中调用上传时,更新的状态对您不可用。将状态传递给上传方法的最简单解决方案

import React, { useCallback, useState } from 'react';
const HomeScreen = () => {
    const initialState = {
        error: false,
        files: [],
        totalSize: 0,
        finished: false
    };
    const [state, setState] = useState(initialState);
    const upload = useCallback((updatedState) => {
        // At this point state.files is an empty array
        console.log((updatedState || state).files);
    }, [state]);
    const clickHandler = useCallback(() => {
        const queue = [
            { id: 1, bool: false },
            { id: 2, bool: false }
        ];
        setState((state) => {
            const updatedState = { ...state, files: queue }
            upload(updatedState )
            return updatedState;
        });
        upload()
    }, [upload]);
    return <button onClick={clickHandler}>Click me</button>;
};
export default HomeScreen;

为了使您的upload()函数能够访问当前状态,必须从useEffect()调用它。看看这对你有用吗?

const HomeScreen = () => {
    const initialState = {
        error: false,
        files: [],
        totalSize: 0,
        finished: false
    };
    
    const [state, setState] = React.useState(initialState);
    const upload = React.useCallback(() => {
        // At this point state.files is an empty array
        console.log(state.files);
    }, [state]);
    
    React.useEffect(()=>{
      state.files.length ? upload() :  null;
    },[state]);
    const clickHandler = React.useCallback(() => {
        const queue = [
            { id: 1, bool: false },
            { id: 2, bool: false }
        ];
        setState((state) => {
            return { ...state, files: queue }
        });
        //upload()
    }, [upload]);
    return <button onClick={clickHandler}>Click me</button>;
};
ReactDOM.render(<HomeScreen/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

相关内容

  • 没有找到相关文章