Reputation: 197
Here is my issue: I am using react hooks functional components with the newer useState
hook. The useState
hook returns an updater function used to update that state.
The updater function is the issue I am having and this is common knowledge of how React works. The state isn't updated until the dom
re-renders. But I need to send form data onSubmit
over axios
(or fetch
).
const App = () => {
const [username, setUsername] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
setUsername(e.target.elements.form1.value)
axios.post('http://localhost:3000/api', { name: username })
}
return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" name="form1" placeholder="Enter name:" />
<button type="submit">Submit</button>
</form>
</div >
)
}
In this code when the form is submitted with the onSubmit
event on the form tag, the handleSubmit()
function is called. Here the setUsername()
updater function is going to update the sate and axios
runs a post call to a backend server. But the axios.post
will always only send the previous state value because the setUsername()
function wont finish until the dom
is re rendered. So the data coming into the backend always appears one step behind.
What is the best method to do this correctly? With my form inputs I don't really need them to be rendered to the dom
, I just need the form info to be passed to the backend. Should I not even put this data in the state? And if so whats the best way to do this with a large form; say 10 inputs values?
I also have seen people use value={some state value} in the input form for two way binding; but that makes using more then one input in a form very difficult using hooks. Unless there is some magical way I missed.
I have just never seen the 'standard' way of performing axios
or fetch calls in react with Hooks. I have searched the web a lot but there doesn't seem to be a lot of information on it.
Upvotes: 1
Views: 3855
Reputation: 21297
State's updates are asynchronous (with hooks
the value will only be updated in the next render).
But you already know what value
looks like cause is inside your scope already. Just pass it to axios
const App = () => {
const [username, setUsername] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
const { value } = e.target.elements.form1
setUsername(value)
axios.post('http://localhost:3000/api', { name: value })
}
return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" name="form1" placeholder="Enter name:" />
<button type="submit">Submit</button>
</form>
</div >
)
}
Upvotes: 10