I've been working on my first React Project, a CV application where users can input their information and generate a CV. After the user submits the form, the form should disappear and the relevant info displayed on the page. Unfortunately, nothing is displayed after the input boxes are filled, and it seems like the state values become empty after pressing the submit button. Also, the input fields disappear even before I press the submit button.
Here's the code -
import React, { useState } from 'react';
export default function Info(){
const [person, setPerson] = useState({
full_name: "",
email_ID: "",
phone_number: "",
edit_mode: true
});
const changeHandler = (e) =>{
setPerson({ [e.target.name] : e.target.value })
}
const submitHandler = (e) =>{
e.preventDefault();
setPerson({
edit_mode: false
});
}
const editHandler = (e) =>{
setPerson({
edit_mode: true
})
}
const editContent = (
<div>
<form onSubmit={submitHandler} >
<input
type = "text"
value = {person.full_name}
placeholder='Enter Your Full Name'
onChange={changeHandler}/>
<br/>
<input
type = "email"
value = {person.email_ID}
placeholder='Enter Your Email ID'
onChange={changeHandler}/>
<br/>
<input
type = "tel"
value = {person.phone_number}
placeholder='Enter Your Phone Number'
onChange={changeHandler}/>
<br/><br/>
<button type="submit" className="submit-button">SUBMIT</button>
</form>
</div>
)
const submittedContent = (
<div>
<button onClick={editHandler} className="edit-button">EDIT</button>;
<h2>{person.full_name.toUpperCase()}</h2>
<br/>
<p>{person.email_ID}</p>
<p>|</p>
<p>{person.phone_number}</p>
</div>
)
return(
<>
{person.edit_mode ? editContent : submittedContent}
</>
)
}
Is there a way to fix this without involving the use of additional React Hooks, since I'm just starting out with React and want to implement this using only the useState hook. Thanks!!
There are few problems in your code,
You are updating state without persisting the previous values in changeHandler
and submitHandler
. This will lead to overwriting of existing values with the values which you are setting. While setting you can spread the values and set as:
const changeHandler = (e) => {
const newValue = { ...person, [e.target.name]: e.target.value };
setPerson(newValue);
};
You are accessing name in e.target.name
but you are not giving name to the fields inside render. You can give name as:
<input
name="full_name"
type="text"
value={person.full_name}
placeholder="Enter Your Full Name"
onChange={changeHandler}
/>
I have created a codesandbox with working example. Please check this out.
Full code:
import React, { useState } from "react";
export default function Info() {
const [person, setPerson] = useState({
full_name: "",
email_ID: "",
phone_number: "",
edit_mode: true,
});
const changeHandler = (e) => {
const newValue = { ...person, [e.target.name]: e.target.value };
setPerson(newValue);
};
const submitHandler = (e) => {
e.preventDefault();
setPerson({ ...person, edit_mode: false });
};
const editHandler = (e) => {
setPerson({ ...person, edit_mode: true });
};
const editContent = (
<div>
<form onSubmit={submitHandler}>
<input
name="full_name"
type="text"
value={person.full_name}
placeholder="Enter Your Full Name"
onChange={changeHandler}
/>
<br />
<input
name="email_ID"
type="email"
value={person.email_ID}
placeholder="Enter Your Email ID"
onChange={changeHandler}
/>
<br />
<input
name="phone_number"
type="tel"
value={person.phone_number}
placeholder="Enter Your Phone Number"
onChange={changeHandler}
/>
<br />
<br />
<button type="submit" className="submit-button">
SUBMIT
</button>
</form>
</div>
);
const submittedContent = (
<div>
<button onClick={editHandler} className="edit-button">
EDIT
</button>
<h2>{person.full_name.toUpperCase()}</h2>
<br />
<p>
{person.phone_number} | {person.email_ID}
</p>
</div>
);
return <>{person.edit_mode ? editContent : submittedContent}</>;
}