簡體   English   中英

狀態無法通過React掛鈎進行更新

[英]State does not get updated with React hooks

我以為我的腦袋在鈎子上。 但是,我正在為此苦苦掙扎。 下面的代碼是我用於演示的實際代碼的非常簡化的版本。 實際上, 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;

使用鈎子狀態更新程序進行狀態更新是異步的,因此,當您在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> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM