I am new to react and I am trying to make an application that gets the output from a form and displays it in a div. So far, I have only managed to get the result from the form with a simple useState() approach.
To display it, I have tried creating a variable "isSubmitted" to keep track whether or not the variable was submitted, in order to display it only when the user stops typing!
const Example0 = () => {
var isSubmitted;
const [email, setEmail] = useState("");
const handleEmail = (event) => {
setEmail(event.target.value);
isSubmitted = false;
console.log(isSubmitted);
};
const handleSubmit = (event) => {
event.preventDefault();
isSubmitted = true;
console.log(isSubmitted);
};
return (
<Fragment>
<h1>Form example</h1>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Email</label>
<input id="email" type="text" value={email} onChange={handleEmail} />
</div>
<button type="submit">Submit</button>
</form>
<div>{isSubmitted ? email : "no user"}</div>
</Fragment>
);
};
This part, does not work. The email variable changes but the display doesn't. Does it have something to do with how React works? I come from a HTML background.
<div>{isSubmitted ? email : "no user"}</div>
Help is much appreciated.
CodePudding user response:
Your page needs to be rendered, so you can see the data already in your page.
In reactJS, there are states,
The state is a built-in React object that is used to contain data or information about the component. A component's state can change over time; whenever it changes, the component re-renders. source
So you need to use a state to make your component renders again and see the data.
simply create a new state like this:
const [isSubmitted, setIsSubmitted] = React.useState(false);
then change the states when you need, In your example you have to use it like this:
const handleEmail = (event) => {
setEmail(event.target.value);
setIsSubmitted(false);
console.log(isSubmitted);
};
const handleSubmit = (event) => {
event.preventDefault();
setIsSubmitted(true);
console.log(isSubmitted);
};
CodePudding user response:
You should be using a state to control the boolean for if the user has submitted their email or not.
Why can't you use a normal variable?
Every time you're updating a state variable, the component will re-render, and each time it re-renders, you're setting your isSubmitted
flag to an undefined. Additionally, even if it wasn't undefined, it wouldn't update your component to show the email because non-state variables won't trigger a re-render, so updating isSubmitted to true won't trigger your ternary statement you have, and re-rendering it will just take it back to undefined, which leaves both scenarios without a render of your div tag content.
Solution
If you want something to conditionally render, you should use useState
, its the whole point of react, to "react" accordingly and update your DOM. It's one of the biggest issues I see new learners grasp when first touching React.
Here's my approach to it, which won't update the end tag to whatever the value is after you submit it (I assume you'd want this implemented):
const [email,setEmail] = useState("");
const [isSubmitted, setIsSubmitted] = useState(false);
/**
* handles the Email input, does not update if the form has been submitted or if the string is empty.
* @param {*} e
*/
const handleEmail = (e) => {
if(e.target.value.length > 0 && isSubmitted === false) {
setEmail(e.target.value);
}
};
const handleSubmit = (e) => {
e.preventDefault();
setIsSubmitted(true);
};
return (
<>
<h1>Form example</h1>
<form onSubmit={(e) => handleSubmit(e)}>
<div>
<label htmlFor="email">Email</label>
<input id="email" type="text" onChange={handleEmail} />
</div>
<button type="submit">Submit</button>
</form>
{isSubmitted ? <p>Thank you for submitting your email: {email}</p> : null}
</>