Reputation: 695
I'm trying to create an input form that stores information in a component's state variable, then outputs that variable on the screen. I read the docs on controlled components, and that's what I'm attempting here.
My main issue here is when I click submit, the correct text appears on the screen, but then the entire page refreshes and I'm not sure why. From what I've read online, refs
appear to be a solution, but my understanding is that I can use either that, or controlled components.
class InputField extends React.Component {
constructor(props) {
super(props);
this.state = {
itemName: "",
storedItemName: "",
};
this.handleNameChange = this.handleNameChange.bind(this);
this.afterSubmission = this.afterSubmission.bind(this);
}
handleNameChange(event) {
this.setState({
itemName: event.target.value
});
}
afterSubmission(event) {
let name = this.state.itemName;
this.setState ({
storedItemName:this.state.itemName
}, function() {
alert(this.state.storedItemName); // Shows the right value!
});
}
render() {
return(
<div>
<form onSubmit = {this.afterSubmission}>
<label> Item Name:
<input
type = "text"
name = "itemName"
value = {this.state.itemName}
onChange = {this.handleNameChange}
/></label>
<input type = "submit" value = "Submit" />
</form>
<div className = "itemList">
<p>Hi</p>
{this.state.storedItemName}
</div>
</div>
);
}
Upvotes: 66
Views: 136026
Reputation: 6554
In my case, the <form>
was not actually needed. Just removing it fixes this issue.
Upvotes: -1
Reputation: 99
To prevent basic React form submit from refreshing the entire page, we call e.preventDefault. in the submit event handler.
For instance, we write:
import React from "react";
export default function App() {
const onSubmit = (e) => {
e.preventDefault();
console.log("refresh prevented");
};
return (
<div>
<form onSubmit={onSubmit}>
<button type="submit">submit</button>
</form>
</div>
);
}
to create the onSubmit function that’s set as the value of the onSubmit prop.
In the function, we call e.preventDefault to prevent the default submission behavior, which is to do server side form submission which refreshes the whole page.
We have a submit button in the form to do the form submission.
Therefore, instead of seeing the page refresh when we click submit, we should see the 'refresh prevented' string logged in the console instead.
Upvotes: 9
Reputation: 771
There are 3 ways you can do this:
1st WAY
By using event.preventDefault();
function
InputField.js
class InputField extends React.Component {
state = {
itemName: "",
storedItemName: "",
}
handleNameChange = (event) => {
const { name,value } = event.target;
//we can't write this.setState({name:value}) this will set name as the key we need value of the name which is itemName
this.setState({
[name] : value //itemName:"the text we will enter"
});
}
afterSubmission = (event) => {
event.preventDefault();
this.setState ({
storedItemName:this.state.itemName
}, function() {
alert(this.state.storedItemName);
});
}
render() {
return(
<div>
<form onSubmit = {this.afterSubmission}>
<label> Item Name:
<input
onChange = {this.handleNameChange}
type = "text"
name = "itemName"
value = {this.state.itemName}
/>
</label>
<input type = "submit" value = "Submit" />
</form>
<div className = "itemList">
<p>Hi</p>
{this.state.storedItemName}
</div>
</div>
);
}
}
export default InputField;
2nd WAY
By removing onSubmit event from form element
Next is change the input type of submit to input type button and add an onClick event to it
InputField.js
class InputField extends React.Component {
state = {
itemName: "",
storedItemName: "",
}
handleNameChange = (event) => {
console.log(this);
const { name,value } = event.target;
this.setState({
[name] : value
});
}
afterSubmission = () => {
this.setState ({
storedItemName:this.state.itemName
}, function() {
alert(this.state.storedItemName);
});
}
render() {
return(
<div>
<form>
<label> Item Name:
<input
onChange = {this.handleNameChange}
type = "text"
name = "itemName"
value = {this.state.itemName}
/>
</label>
<input
type = "button"
onClick={this.afterSubmission}
value = "Submit"
/>
</form>
<div className = "itemList">
<p>Hi</p>
{this.state.storedItemName}
</div>
</div>
);
}
}
export default InputField;
3rd WAY
By using react form hook (https://www.react-hook-form.com/)
npm install react-hook-form
InputField.js
import InputFieldForm from 'location specified';
class InputField extends React.Component {
render() {
return(
<div>
<InputFieldForm />
</div>
);
}
}
export default InputField;
InputFieldForm.js
import React from "react";
import { useForm } from "react-hook-form";
const InputFieldForm = () =>{
const onSubmit = (formData) =>{
alert(JSON.stringify(formData));
console.log(formData);
}
const { register, handleSubmit } = useForm();
return(
<form onSubmit = {handleSubmit(onSubmit)}>
<label> Item Name:
<input
{...register('itemName')}
type = "text"
name = "itemName"
/>
</label>
<input type = "submit" value = "Submit" />
</form>
)
}
export default InputFieldForm;
Upvotes: 5
Reputation: 85593
Prevent the default behaviour:
afterSubmission(event) {
event.preventDefault();
let name = this.state.itemName;
this.setState ({
storedItemName:this.state.itemName
}, function() {
alert(this.state.storedItemName); // Shows the right value!
});
}
Upvotes: 17
Reputation: 16482
Just call event.preventDefault
method to prevent default behavior of form
afterSubmission(event) {
event.preventDefault();
let name = this.state.itemName;
this.setState ({
storedItemName:this.state.itemName
}, function() {
alert(this.state.storedItemName); // Shows the right value!
}
}
Upvotes: 115