首页 > 解决方案 > 当它已经在 useEffect 回调中设置时,为什么在 const 中未定义 useState 变量?

问题描述

我正在尝试访问由 useState 创建的变量,但是当我尝试访问它时它是未定义的。当我使用 useClick 调用该函数时,我可以访问它,但当我将它放在 useEffect 中时不能访问它。

function Viewer(props) {
    
    const [lines, setLines] = useState()
    const [linesToDisplay, setLinesToDisplay] = useState()

    useEffect(() => {

        if (props.json != undefined) {
            let l = props.json.lines.map((item => <Line json={item} />))
            setLines(l) // Lines are set.
            setLinesToDisplay(
                renderLinesAsColumns // Next, call renderLinesAsColumns.
            )
        }
       
    }, []
    )

    const renderLinesAsColumns = () => {

        var result = []

        lines.forEach(line => { // ERROR: "lines is undefined". But lines was already set!
            result.push(line) 
        })

        setLinesToDisplay(result) // set lines to display
    }


}

为什么会这样?我可以确认lines之前已经设置过renderLinesAsColumns被调用过。

标签: javascriptreactjs

解决方案


误解是当你打电话时

setLines(l) // Lines are set.

它实际上是

setLines(l) // Lines will be set, the next time we render.

但是由于您renderLinesAsColumns在下一次渲染之前调用,所以当您调用它时,lines仍然是未定义的。然后当它再次渲染时,它永远不会renderAsLinesAsColumns用更新的值调用。

你可能想做:

useEffect(() => {
    if (props.json != undefined) {
        let l = props.json.lines.map((item => <Line json={item} />))
        setLines(l) // Lines are set.
    }
}, [])
useEffect(() => {
    if (lines && lines.length) {
        setLinesToDisplay(
            renderLinesAsColumns // Next, call renderLinesAsColumns.
        );
    }
}, [lines])

推荐阅读