状态(来自 useState)在回调中使用旧值

时间:2021-07-01 13:55:21

标签: reactjs react-hooks

我有一个包含文件上传组件的表单,该组件在上传结束时调用 props.onFileAdded 回调。

axios.post(UPLOAD_URL, data, config)
        .then(function (res) {
            const {data} = res

            if (props.onFileAdded)
                props.onFileAdded(props.index, data)
        })
        .catch(function (err) {
            console.log(err)
        })

我的问题是我的 indexList 状态在执行该回调时被重置(onFileAdded 作为 onFileAdded 属性传递):

const [indexList, setIndexList] = useState()
//... 
function addItem() {
    logger.debug("indexList was: ", ": ", indexList?.length, ":", indexList)
    const newIndexList = indexList == null ? [] : [...indexList]
    newIndexList.push(newIndexList.length)
    logger.debug("indexList became: ", newIndexList.length, ": ", newIndexList)
    setIndexList(newIndexList)
}

function onFileAdded(index, uploadedFile) {
    logger.debug("onFileAdded called")
    addItem()
}

为了仔细检查我的问题,我在父组件中添加了一个按钮

    <Button onClick={addItem}>Add Item</Button>

当我点击那个按钮时,我的状态会按预期更新,但是当我上传文件时它会重置:

_app.js?ts=1625147479051:16572 indexList was:  :   : 
_app.js?ts=1625147479051:16572 indexList became:  1 :  0
_app.js?ts=1625147479051:16572 Rendering with index list:  0
_app.js?ts=1625147479051:16572 indexList was:  :  1 : 0
_app.js?ts=1625147479051:16572 indexList became:  2 :  0,1
_app.js?ts=1625147479051:16572 Rendering with index list:  0,1
_app.js?ts=1625147479051:16572 indexList was:  :  2 : 0,1
_app.js?ts=1625147479051:16572 indexList became:  3 :  0,1,2
_app.js?ts=1625147479051:16572 Rendering with index list:  0,1,2
_app.js?ts=1625147479051:16572 starting to upload
_app.js?ts=1625147479051:16572 file load finished
_app.js?ts=1625147479051:16572 onFileAdded called
_app.js?ts=1625147479051:16572 indexList was:  :   : 
_app.js?ts=1625147479051:16572 indexList became:  1 :  0
_app.js?ts=1625147479051:16572 Rendering with index list:  0

我在这里找到了答案,但我不知道该怎么做 onChange is resetting state - useState

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

这可能是因为 addItem() 函数有一个对您的 indexList 的旧引用

来自react docs:

<块引用>

如果新状态是使用之前的状态计算出来的,你可以传递一个函数给 setState。该函数将接收先前的值,并返回更新的值。

尝试将您的 addItem 函数更改为:

function addItem() {
  setIndexList((oldIndexList) => {
    logger.debug("indexList was: ", ": ", oldIndexList?.length, ":", oldIndexList)
    const newIndexList = oldIndexList == null ? [] : [...indexList]
    newIndexList.push(newIndexList.length)
    logger.debug("indexList became: ", newIndexList.length, ": ", newIndexList)
    return newIndexList;
  })
}