I am having trouble saving data to a database and then conditionally rendering the components in react.
I want to display a message box, save the message to a database, and then remove the message box and display a thank you
message.
For context this is react code in a next.js
framework.
User navigates to the contact page at contact/index.js
. The default function is
import { useState } from 'react';
import style from '@/styles/general.module.css';
export default function MessageFlow () {
const [isSubmitted, setSubmitted] = useState(false);
return (
<>
{
isSubmitted ? (
<p className={style.centerText}>Thank you. We will be in touch.</p>
) : (
<>
<Messageform
isSubmitted={false}
onShow={() => setSubmitted(true)}
/>
</>
)
}
</>
);
}
In the same file above <Messageflow />
is <Messageform />
which is
function Messageform({ onShow }) {
return (
<>
<h1 className={style.centerText}>
Contact
</h1>
<form onSubmit={handleSubmit}>
<textarea type="text" id="messageText" className={style.messageBox} placeholder=" General feedback"/>
<br></br>
<button type="submit" onClick={onShow} className={style.greenButtonCont}>Submit</button>
</form>
</>
)
}
And above this is handleSubmit
as
const handleSubmit = async (note) => {
note.preventDefault();
const data = {
noteData: note.target.messageText.value
}
const JSONdata = JSON.stringify(data)
const endpoint = '/api/messageForm'
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSONdata,
}
await fetch(endpoint, options);
}
So here's the issue: with the code exactly as written, the message box disappears and Thank you. We will be..
appears, but the message is not saved to the database. The error Form submission canceled because the form is not connected contact:1
displays in the browser dev tools.
One answer on S.O. here talks about manipulating the DOM, but React specifically says not to touch the DOM. Also, this is just simple form submission, so I don't think you need to touch the DOM for that.
The other answer here talks about how you should not have an onClick
handler on the button where you have type="submit"
.
I do have an onClick
handler on my button that has submit
because that is where I update isSubmitted
state to true
. Updating isSubmitted
is what causes the message box to disappear and the Thank you
message to appear.
I've tried to update isSubmitted
within handleSubmit
but this is where it gets complicated.
If I simply pass in isSubmitted
like <form onSubmit={handleSubmit(isSubmitted)}>
and place setSubmitted(true)
within the const handleSubmit = async (note) => ..
function then I get a runtime error of
TypeError: note.preventDefault is not a function
I think this is because isSubmitted
is not an event object, so you can't do note.preventDefault on that.
I've also tried to destructure the arguments in both the <form ..
part and the const handleSubmit = async
part and use different combinations such as
<form onSubmit={handleSubmit({ isSubmitted })>
...
const handleSubmit = async ({isSubmitted})
but results ReferenceError: note is not defined
.
<form onSubmit={handleSubmit({ isSubmitted })>
...
const handleSubmit = async ({note, isSubmitted})
results TypeError: note.preventDefault is not a function
.
Tried dummy variable
<form onSubmit={handleSubmit({ _a, isSubmitted })>
...
const handleSubmit = async ({note, isSubmitted})
results ReferenceError: _a is not defined
.
When I delete onClick={onShow}
from <button type="submit"..
the message does save to my database; but the message box stays there and no thank you
message appears.
I tried moving everything to onClick
but read that you shouldn't use a button onClick
function to submit form data because then you're not able to respond to submit events. I think that's a similar issue when I try to pass in isSubmitted
to handleSubmit
. It makes note
no longer an event.
So how do I save the message, update the state, remove the message box, and then display the thank you
message? Seems I need both handleSubmit
and onSubmit
, but both together is causing the issue.