首页 > 解决方案 > React 钩子中的状态不会立即改变

问题描述

我在调用 onChange 事件后正在更改状态,它不会立即反映。我怎样才能让我的状态立即改变。这是我的父组件代码。

import React from 'react';
import {One, test, test1} from './Sample/SampleData';

export const FirstUser = () => {
    const [data, setData] = React.useState(One)
    const [id, setId] = React.useState("")
    
    React.useEffect(()=> {
            onChangeId(id)
    },[id])

const onChangeId = (myId:string) => {
    setId(myId)
    switch (myId) {
        case '1':
            setData(test);
            break;
        case '2':
            setData(test1);
            break;
        default:
            setData(One);
            break;
    }
}
    return (
        <div>
            <ChildComponent
                firstData={One} 
                onChangeId={onChangeId} 
                secondData={data}
            />
        </div>
    );
};

下面是我的 ChildComponent 代码 -

import React from 'react';

export const ChildComponent = ({
    firstData,
    onChangeId,
    secondData
}: NewInterface) => {
const [format, setFormat] = useState(secondData);
const onChange = (
        type: string,
        val:string
    ) => {
        
        if (type === "welcome") {
                onChangeId(val);
                setFormat(secondData);                
                console.log(secondData , "secondData")                
        }
    };
    return (
        
            <React.Fragment>                
                <AnotherChildComponent
                    onChange={onChange}
                    firstData={firstData}
                    newData={format}
                />
            </React.Fragment>
    
    );
}

AnotherChildComponent 的代码是 -

import React from 'react';

export interface SomeInterface {
    onChange: (
        type: string,
        val:  string
    ) => void;
    
    firstData: DataInterface,
    newData: DataInterface
}

export const AnotherChildComponent = ({
    onChange,
    firstData,
    newData
}: SomeInterface) => {
    let { oneData, twoData } = firstData;
    let { thirdData } = newData;

    const translatedOneData = oneData.map(({ label, value }) => ({
        label: translateFn!(label),
        value
    }));

    const translatedTwoData = twoData.map(({ label, value }) => ({
        label: translateFn!(label),
        value
    }));

    const translatedThreeData = thirdData.map(({ label, value }) => ({
        label: translateFn!(label),
        value
    }));
console.log(newData, "newData")
    return (
        <React.Fragment>
                
                    <Grid container>
                        <Select
                            options={translatedTwoData}
                            value={selectedTwoData}                         
                            onChange={(val: string) =>
                                onChange('welcome', val)
                            }
                        />
                        <SectionLabel label="Newdata" />
                        <Select
                            options={translatedThreeData}
                            value={selectThirdData}
                            onChange={(val: string) =>
                                onChange('guest', val)
                            }
                        />
                    </Grid>
                
            
        </React.Fragment>
    );
};

设置 setFormat 的状态后,当我在 ChildComponent 中安慰 secondData 时,它会在第二次更改时显示数据。第一次更改时(立即)不显示数据。意味着当我调用 onChangeId 两次时,我得到了想要的 secondData。它没有立即显示。我使用了 useEffect 并id & data一一传递,但仍然在两次调用时更改数据。那么任何人都可以帮助我吗?

标签: reactjstypescript

解决方案


您首先应该知道useStatemutate 回调是异步的,因此您console.log(...)在调用回调后将始终显示旧值。但是,我很确定 UI 更新工作正常,除非您向我们展示AnotherChildComponent.

无论哪种方式,您console.log将始终输出与挂载时间相同的值,因为那是它被定义的时间。

而且WARNING,如果您对调用onChangeId父组件的方式不小心,则可能会导致递归。


推荐阅读