I would like to reflect state asynchronously. But when I add a value, it is not reflected asynchronously. How can I solve this problem?
const [values, setValues] = useState<string[]>([])
const [input, setInputs] = useState<string>()
const add = useCallback(() => {
if(!input) return
values.push(input)
setValues(values)
}, [input, values])
...
<input onChange={() => setInput(e.target.value) />
<button onClick={() => add()}>Add</button>
// not displayed asynchrnously
{values && values.map((value, idx) => {
return (
<div key={idx}>{value}</div>
)
})}
...
CodePudding user response:
When setting the existing state based on the previous state, the recommended way to do it is to send a callback function to the state setting function.
I have modified your add
function to reflect this:
const add = useCallback(() => {
if (input) {
setValues(prev => [...prev, input])
}
}, [input, setValues])
Also, your callback function for setting the input was missing the event parameter and had a typo. I have fixed both issues:
<input onChange={e => setInput(e.target.value)} />