我似乎无法从此函数访问更新后的状态

时间:2019-12-14 20:57:34

标签: javascript reactjs closures react-hooks

我处于这种状态:

const [fingerprintingIssues, setFingerprintingIssues] = React.useState([])

我有一个遍历一堆数据进行验证的功能。如果有错误,它将与fingerprintingIssues一起添加到setFingerprintingIssues中。很好。

但是在此方法(缩写)中,我正在方法fingerprintingIssues内检查complete,并且它始终返回[]。我已经读到这是闭包和陈旧状态的问题,但我似乎看不出这在这里如何适用。

const validateDocument = data => {
    const start = moment()
    try {
        Papa.LocalChunkSize = 10485
        return Papa.parse(data, {
            complete: () => {
                // Log completion only if it’s been 20 seconds or more
                const end = moment()
                const duration = moment.duration(end.diff(start))
                const seconds = Math.ceil(duration.asSeconds())
                if (seconds < MIN_PROCESS_TIME) {
                    setTimeout(() => {
                        setUploadStep('tagging')
                        console.log('fingerprintingIssues', fingerprintingIssues)
                    }, (MIN_PROCESS_TIME - seconds) * 1000)
                } else {
                    setUploadStep('tagging')
                }
            },
            error: () => {
                setDocumentError(true)
                setDocumentReady(false)
            },
        })
        …

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我认为确实存在关闭和陈旧状态的问题。使用挂钩时,您需要谨慎使用回调。

您的组件函数被调用多次(每个渲染一次)。每个呼叫将收到一个特定的状态。您可以将其想像成特定状态与该特定渲染相关联。如果在渲染中创建回调,则该回调将存在于其创建所在的渲染的闭包中。问题是,如果重新渲染组件,则该回调仍存在于旧渲染的闭包中,并且将没有看到新状态。

解决此问题的一种方法是使用React.useRef,您可以阅读有关here的更多信息。引用具有一个值,可以随时进行修改和访问,而无需关闭。请注意,修改参考不会导致您的组件重新呈现。

const fingerPrintingIssues = React.useRef([])
const validateDocument = data => {
    // Perform validation
    // Now access (refs are accessed by .current)
    console.log(fingerPrintingIssues.current)
}

// Modify:
fingerPrintingIssues.current.push(...)

如果在修改值时需要重新渲染组件,则可以结合使用useRef()和useState()。