首页 > 解决方案 > 使用 setState 时如何立即获取更新状态?

问题描述

我有一个ViewColumn组件。我使用registerColumn方法refsView上下文中存储列:

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>

我真正感到困惑的是Column组件。每当我尝试注册该列并在之后获取更新的长度时,它都不会按时更新,因为它setState是异步工​​作的:

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}`);
}, []);

[...]

文档说,我可以使用useEffectwithcolumns作为依赖项,并在下一次渲染时更新长度。但是,我需要在registerColumn调用后立即使用更新的状态 - 使用另一个 useEffect基本上意味着破坏执行上下文和延迟任务的需要,加上可能引入其他回调只是为了解决这个问题。

我是 React 的新手,但我很确定还有其他可能解决这个问题,所以任何帮助都将不胜感激。

标签: javascriptreactjsreact-hooksstatereact-context

解决方案


更新 useEffect 中的 setState 和 useEffect 中的控制台日志将不起作用,因为 useState 异步工作并且对所有状态做出反应并更新一次。它正在更新状态,但它不会反映那个时刻,因为会通过更新对批次做出反应。
您可以使用其他具有列依赖性的 useEffect,因此每次 registerColumn 更新时,都会调用第二个 useEffect 并控制台记录该值。

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


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


推荐阅读