简体   繁体   中英

How do I get updated state immediately when using setState?

I have a View and Column components. I use registerColumn method to store column refs in the View context:

const [columns, setColumns] = useState([]);

const registerColumn = (node) => {
    const column = {
        someUniqueId: Math.random(),
        node,
        // more props
    };

    setColumns(prev => [...prev, column])
}

const context = {
    columns,
    registerColumn
}

<ViewContext.Provider values={context}>
    <View>
        <Column/>
        <Column/>
        <Column/>
    </View>
    <View>
        <Table/>
    </View>
</ViewContext.Provider>

Where I'm getting really confused is the Column component. Whenever I try to register the column and get the updated length afterwards, it's not being updated on time, because setState works asynchronously:

const {columns, registerColumn} = useContext(ViewContext);
const ref = useRef(null);

useEffect(() => {
    registerColumn(ref.current);

    // Here is where updated column length but it keeps saying it's 0 length
    console.log(`Hello from column number ${columns.length}`);
}, []);

[...]

Docs are saying, that I can make use of the useEffect with the columns as the dependency and have the updated length on next render. However, I need to consume updated state right after registerColumn is invoked - using another useEffect will basically mean breaking execution context and the need to delay the task, plus possibly introduce other callbacks just to get around this.

I'm new to React but I'm pretty sure there are other possibilities to get around this, so any help will be greatly appreciated.

Updating setState in useEffect and console log in useEffect won't work, because useState works async and react batches all state and update it once. It is updating the state but it won't reflect that that monent because react batches with updates.
You can use other useEffect with dependency of columns, so every time registerColumn updates, second useEffect will be called and console log the value.

useEffect(() => {
    registerColumn(ref.current);
}, []);


useEffect(() => {
    console.log(`Hello from column number ${columns.length}`);
},[columns]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM