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.