Reputation: 2662
I have a form with a file upload component that calls a props.onFileAdded
callback when the upload ends.
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)
})
My issue is that my indexList
state is reset when that callback is executed (onFileAdded
is passed as the onFileAdded
property):
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()
}
To double check my problem I added in the parent component a button
<Button onClick={addItem}>Add Item</Button>
And when I click that button, my state is updated as expected, but when I upload a file it is reset:
_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
I found an answer here, but I can't figure out what to do onChange is resetting state - useState
Thanks for your help!
Upvotes: 3
Views: 5219
Reputation: 1061
It is probably because the addItem()
function has an old reference to your indexList
From the react docs:
If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value.
Try changing your addItem
function to this:
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;
})
}
Upvotes: 4