I have a simple form build in react js. It has a text area with a submit button. Now I want to add an OnBlur functionality in this form. I tried this in the render method:
render() {
return (
<form onSubmit={this.handleSubmit}> onBlur={this.onBlur}
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
But this is not working. The original code( from FaceBook Tutorials) is as follows: Please note that I know that I need to bind the onBlur() through these lines: this.onBlur = this.onBlur.bind(this);. So that is not an area of Concern.
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Related
I am new to React and I am trying to make a form I wrote this simple form
class Profile extends React.Component {
constructor(props) {
super(props);
this.state = {name: '', age:''};
this.handleNameChange = this.handleNameChange.bind(this);
this.handleAgeChange = this.handleAgeChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleNameChange(event) {
this.setState({name: event.target.name});
}
handleAgeChange(event) {
this.setState({age: event.target.age});
}
handleSubmit(event) {
alert('Name was submitted: ' + this.state.value);
alert('Age was submitted: '+ this.state.age);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.name} onChange={this.handleNameChange} />
</label>
<label>
Age:
<input type="text" value={this.state.age} onChange={this.handleAgeChange}/>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
export default Profile;
When I try it I can't write anything in the Name and the alert always shows me 'Name was submitted: undefined' 'Age was submitted: undefined'
You have a few typos in your code. For each of your handleChange functions, you should have event.target.value for the state value being set instead of the names of the fields.
Also in your alert function for the name, the value should be this.state.name instead of this.state.value.
Here is a complete working version:
class Profile extends React.Component {
constructor(props) {
super(props);
this.state = { name: "", age: "" };
this.handleNameChange = this.handleNameChange.bind(this);
this.handleAgeChange = this.handleAgeChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleNameChange(event) {
this.setState({ name: event.target.value });
}
handleAgeChange(event) {
this.setState({ age: event.target.value });
}
handleSubmit(event) {
alert("Name was submitted: " + this.state.name);
alert("Age was submitted: " + this.state.age);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
type="text"
value={this.state.name}
onChange={this.handleNameChange}
/>
</label>
<label>
Age:
<input
type="text"
value={this.state.age}
onChange={this.handleAgeChange}
/>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<Profile / > ,
document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
I have a form containing several inputs and I am handling multiple user inputs but I want to display all the inputs when the submit button is clicked.
What do I need to add/change in my code to display the inputs when they are submitted?
class Planning extends React.Component {
constructor() {
super()
this.state = {
title: '',
goal: '',
tech: '',
features: '',
details: ''
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
})
}
handleSubmit(event) {
alert(`Plan: ` )
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div>
<label class="label-title">
Project Title:</label>
<input name="title" id="title" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-goal">
Motivational Goal: </label>
<input name="goal" id="goal" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-tech">
Technologies/tools:</label>
<input name="tech" id="tech" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-features">
Features:</label>
<input name="features" id="features" type="text" onChange={this.handleChange}/>
</div>
<div>
<label class="label-details">
Other details: </label>
<input name="details" id="details" type="text" onChange={this.handleChange}/>
</div>
<input class="submit" type="submit" value="Submit" />
</form>
)
}
}
The values are stored in the state so you could
handleSubmit(event) {
event.preventDefault();
alert(`Plan:\n${JSON.stringify(this.state,null,2)}`);
}
or the more explicit approach
handleSubmit(event) {
const {
title,
goal,
tech,
features,
details
} = this.state;
event.preventDefault();
alert(`Plan:
Title: ${title}
Goal: ${goal}
Tech: ${tech}
Features: ${features}
Details: ${details}
`);
}
I have two text fields id and name of the user . Below that a submit button .
How can I pass the user name and Id to handleSubmit() on click of the submit buton ?
<input type="text" name="name" id="name" />
<br/>
<label>id : </label>
<input type="text" name="userId" id="userId" />
<br />
<input type="submit" oncClick={()=>this.handleSubmit()}value="Add
user"/>
The value should be saved in the state of the component and updated onChange. Once handleSubmit is called you read the value from the state. const { name } = this.state
class form extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit() {
console.log(this.state.value)
}
render() {
.....
}
}
I am fairly new to React coming from a JS & Java background. I am still understanding react state properties and have two code samples, one which compiles and one which does not. In the first, I establish the class' state as having one variable str and I work with this variable. This code does not work. In the second, the variable is named value, and it works. Is it not possible to have a variable under a different name or more than one variable in react? Thank you!!
Side Note: The term "works" in this context is the difference between being able to type into the text field or not.
Form Code (Works):
class SomeOtherForm extends React.Component {
constructor(props) {
super(props);
this.state = {
str: '',
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleValueChanged(event) {
this.setState({str: event.target.value});
}
handleSubmit(event) {
alert('Y.. ' + this.state.str);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type='text' value={this.state.str} onChange={this.handleChange}/>
</label>
<input type='submit' value='Submit'/>
</form>
);
}
}
Form Code (Doesn't Work):
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
In SomeOtherForm there are a few mishaps:
You're calling this.handleChange for the onChange event, but this method doesn't exist (it needs to be changed from handleValueChanged to handleChange)
You haven't bound both handlers to the constructor (you need to add this.handleChange = this.handleChange.bind(this);)
Fixed:
class SomeOtherForm extends React.Component {
constructor(props) {
super(props)
this.state = { str: '' }
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(event) {
this.setState({
str: event.target.value
})
}
handleSubmit(event) {
event.preventDefault()
alert(`Yo shit isssss.. ${this.state.str}`)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
type='text'
value={this.state.str}
onChange={this.handleChange} />
</label>
<input
type='submit'
value='Submit'/>
</form>
)
}
}
In the first example you named the function handleValueChanged NOT handleChange...
This will fix your problem:
<input type='text' value={this.state.str} onChange={this.handleValueChanged}/>
As a side note state in react is an objectand thats it. So referring to state like this
I establish the class' state as having one variable str and I work
with this variable
Isnt actually technically accurate and makes things sound more confusing than they are.
It's totally possible manage different variables in state.
constructor (props) {
super(props)
this.state = {
name: '',
lastname: ''
}
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleSubmit (event) {
event.preventDefault()
console.log(this.state)
}
handleChange (event) {
const { name, value } = event.target
this.setState({
[name]: value
})
}
render () {
<form onSubmit={this.handleSubmit}>
<input
name='name'
value={this.state.name}
onChange={this.handleChange}
/>
<input
name='lastname'
value={this.state.lastname}
onChange={this.handleChange}
/>
</form>
}
Pay attention to the name of the inputs they should be the same as the variables in your state.
So look at this code below for our example, a simple 2-way data-binding on an input field connecting the field to a property inputValue.
But say you have a more complex page with 30 or more inputs. Are you supposed to write 30+ onChange handlers in the class, all with different names corresponding to the inputs like onNameChange, onEmailChange, onPhoneChange, and so on? Is there no neater, more implicit way to bind inputs than what I have below here?
React.createClass({
getInitialState() {
inputValue: ''
},
render() {
return (
<input
type='text'
value={this.state.inputValue}
onChange={this.onChange} />
);
},
onChange(e) {
this.setState({ inputValue: e.target.value });
}
});
Edit: I suppose I could do this and avoid writing handlers on the class:
<input onChange={ e => this.setState({firstName: e.target.value}) } />
Is that kosher?
React docs has your solution:
https://facebook.github.io/react/docs/forms.html#handling-multiple-inputs
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange(event) {
const target = event.target;
this.setState({
[target.name]: target.value
});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input name="name" type="text" value={this.state.name} onChange={this.handleInputChange} />
</label>
<label>
Email:
<input name="email" type="text" value={this.state.email} onChange={this.handleInputChange} />
</label>
<label>
Pet:
<input name="country" type="text" value={this.state.country} onChange={this.handleInputChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
The neater way would be to have a single onChange handler and pass on the id to it, and store the value with that id. Your solution will look like
React.createClass({
getInitialState() {
},
onChange(e, type) {
this.setState({[type]: e.target.value})
},
render() {
return (
<input
type='text'
value={(this.state.inputValue)? this.state.inputValue: ''}
onChange={this.onChange.bind(this, 'inputValue')} />
<input
type='text'
value={(this.state.emailValue)? this.state.emailValue: ''}
onChange={this.onChange.bind(this, 'emailValue')} />
);
},
onChange(e) {
this.setState({ inputValue: e.target.value });
}
});
The value is given with a ternary operator expression because initially the state is not defined and hence we will get a warning that input is trying to change the uncontrolled input to controlled.
The other way is to have the handler inline like
onChange={ e => this.setState({inputValue: e.target.value}) }
but say you have 30 inputs you need to define their initial state and let it set its value like above, only difference being the value being assigned to it should be with the expression as shown in the first example
The other way to assign value to the input as #MayankShukla suggessted will be
value = {this.state.inputValue || ''}
with getInitialState looking like
getInitialState() {
return {}
},