使用setState时如何立即获得更新状态?

时间:2020-05-11 04:55:49

标签: javascript reactjs react-hooks state react-context

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

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

[...]

医生说,我可以将useEffectcolumns一起使用,并在下一次渲染时具有更新的长度。但是,我需要在调用registerColumn之后立即消耗更新的状态-使用另一个 useEffect基本上意味着破坏执行上下文和延迟任务的需要,并可能引入其他回调只是为了解决这个问题。

我是React的新手,但我很确定还有其他解决方法,因此,我们将不胜感激。

1 个答案:

答案 0 :(得分:-1)

在useEffect中更新setState和useEffect中的控制台日志将不起作用,因为useState异步工作,并对所有状态进行批处理并对其进行一次更新。它正在更新状态,但不会反映该状态,因为对更新进行批处理。
您可以将其他useEffect与列依赖项一起使用,因此每次registerColumn更新时,将调用第二个useEffect并控制台记录该值。

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


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