onChange function for input fields not working - javascript

Trying to change the state of input fields but onChange doesn't seem to be working and input fields are disabled (not letting me type)
constructor() {
super();
this.state = {
title: '',
length: '',
image: '',
source: '',
available: '',
date: '',
errors: {}
}
this.onChange = this.onChange.bind(this);
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
<input value={this.state.length} onChange={this.onChange} type="text"
className="form-control" name="email" placeholder="e.g. 3:36" />

2 things :
Your setState function updates a value in the state based on the event's target node name, and here, the name ("email") does not match the value you are getting in your state (length).
The second error is that your onChange is not bound to your class, calling this.setState will return an error.
You can solve it by changing the value variable in your input :
<input value={this.state.email} onChange={this.onChange} type="text" className="form-control" name="email" placeholder="e.g. 3:36"/>
And converting onChange to an arrow function (or binding it) :
onChange = e => {
this.setState({ [e.target.name]: e.target.value });
}

** UPDATED:
** your main fault, is your are linking your input to a state variable called "length", and the name of the input is "email", they should be the same.
You can make it easier for yourself, you don't need to bind at constructor at all, IF you use arrow functions, so, if your write your function like this:
onChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
}
your constructor and state, will be like this:
constructor() {
super();
this.state = {
title: '',
email: '',
image: '',
source: '',
available: '',
date:'',
errors: {}
}
}
And, in JSX, you still pass your properties the same way, like this:
<input value={this.state.email} onChange={this.onChange} type="text"
className="form-control" name="email" placeholder="e.g. 3:36" />
Full working demo:

Related

Form data won't bind to React component using onChange()

I've been coding up an email service for myself, and got stuck on this React form not changing state when form data is entered. Tracked down the main problem to this React form not changing state via onChange()...
How could I bind state to the React form that updates on every keystroke? Using this form data to pass later into an API call.
'''
class AddContact extends Component {
constructor(props) {
super(props);
this.state = {
'name': '',
'company': '',
'linkedin': '',
'department': '',
'email': 'Not available'
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ value: event.target.value });
}
handleSubmit(event) {
}
render() {
return(
<div>
<form onSubmit = {this.handleSubmit}>
<label>
Name
<input type="text" value={this.state.name} onchange = {this.handleChange}/>
</label>
<label>
Company
<input type="text" value={this.state.company} onchange = {this.handleChange}/>
</label>
<label>
LinkedIn Profile
<input type="text" value={this.state.linkedin} onchange = {this.handleChange}/>
</label>
<label>
Department
<input type="text" value={this.state.department} onchange = {this.handleChange}/>
</label>
<label>
Email (Optional)
<input type="text" value={this.state.email} onchange = {this.handleChange}/>
</label>
<input type="submit" value="Submit" />
</form>
</div>
);
}
}
'''
You're not changing the actual form values in state. This line: this.setState({ value: event.target.value }); Changes the value of the value key in the state. So if you were to call this this.setState({ value: 'potato' }); then your state would look like this:
this.state = {
'name': '',
'company': '',
'linkedin': '',
'department': '',
'email': 'Not available',
'value': 'potato'
}
So you need to pass in the actual field name you're trying to change into the onChange function. And that's another thing, you have a typo. The handler is called onChange, with camel case. Yours is incorrectly all lower case.
So here's a correct example of updating the 'name' field. Firstly, update your handleChange function to this:
handleChange(field, value) {
this.setState({ [field]: value });
}
Then change your inputs to be like this:
<input type="text" value={this.state.name} onChange={e => this.handleChange('name', e.target.value)}/>

React.JS Typescript - OnChange says "A component is changing a controlled input of type text to be uncontrolled in OnChange" for State Object

Good day,
I'm new with react.js I'm trying to create a basic data binding using onChange of the input. The problem is, I'm assigning to object with it's properties. Not directly to the property.
Now I'm receiving the error Warning: A component is changing a controlled input of type text to be uncontrolled. when I type-in a character in my inputs.
Here's my code:
interface IProps { }
interface IFloorInfo {
id: number
name: string,
type: string,
condition: string
}
interface IFloorInfoState {
floor: IFloorInfo
}
export default class Floors extends React.Component<IProps, IFloorInfoState> {
state: IFloorInfoState
constructor(props: any){
super(props)
this.state = {
floor: {
id: 0,
name: '',
type: '',
condition: ''
}
}
}
...
render() {
return (
<div>
<input type="text" value={this.state.floor.name} onChange={(e)=>this.inputChanges(e)} />
<input type="text" value={this.state.floor.type} onChange={(e)=>this.inputChanges(e)} />
<input type="text" value={this.state.floor.condition} onChange={(e)=>this.inputChanges(e)} />
</div>
)
}
}
Now this is my inputChanges method that detects if there's a changes in the input
inputChanges = (e:any) => {
this.setState({ floor: e.target.value });
}
Thank you in advance.
The problem is with your following code. According to this code, your state will be {floor: "input value"}
inputChanges = (e:any) => {
this.setState({ floor: e.target.value });
}
But what you actually want is
inputChanges = (e:any) => {
// copying all values of floor from current state;
var currentFloorState = {...this.state.floor};
// setting the current input value from user
var name = e.target.name;
currentFloorState[name] = e.target.value;
this.setState({ floor: currentFloorState });
}
As for multiple properties:
You can add name property to your element and use it in your changeHandler
render() {
return (
<div>
<input type="text" value={this.state.floor.name} name="floor" onChange={(e)=>this.inputChanges(e)} />
<input type="text" value={this.state.floor.type} name="type" onChange={(e)=>this.inputChanges(e)} />
</div>
)
}
For demo, you can refer this https://codesandbox.io/s/jolly-ritchie-e1z52
In this code, you don't specify which property that you want to bind.
inputChanges = (e:any) => {
this.setState({ floor: e.target.value });
}
What you can do, is something like this.
inputChanges = (e:any) => {
this.setState({
...this.state,
floor: { ... this.state.floor, [e.currentTarget.name]: e.currentTarget.value}
})
}
Basically, you're binding whatever property that matches inside your this.state.floor object.

Single onChange function for multiple input fields is not working: ReactJS

Code:
import React, { Component } from 'react';
import { Button, Input, Row, Col, Label } from 'reactstrap';
export default class Settings extends Component {
constructor(props) {
super(props);
this.state = {
tallyPort: '', companyYear: '', interval: '', timeRange: '',
databasePort: '', databaseUserName: '', databasePassword: ''
};
}
handleChange = (stateName, e) => {
this.setState({ stateName: e.target.value });
}
handleSave = () => {
console.log(this.state)
}
render() {
return(
<div className="dashboard" >
<Input name="tallyPort" onChange={this.handleChange.bind(this, 'tallyPort')} />
<Input name="companyYear" onChange={this.handleChange.bind(this, 'companyYear')} />
<Input name="interval" onChange={this.handleChange.bind(this, 'companyYear')} />
<Input name="timeRange" onChange={this.handleChange.bind(this, 'companyYear')} />
<Input name="databasePort" onChange={this.handleChange.bind(this, 'companyYear')} />
<Input name="databaseUserName" onChange={this.handleChange.bind(this, 'companyYear')} />
<Input name="databasePassword" onChange={this.handleChange.bind(this, 'companyYear')} />
<Button style={{ width: '200px', marginLeft: '720px'}} onClick={this.handleSave.bind(this)} color="primary">Save</Button>
</div>
);
}
}
Main problem with this.setState function, I'm not understand why it is not working.
I'm trying to set each state value on "onChange" of input field, "setState" is not working properly, when i'm console all states after given values, it returns blank values, any one help me?
Basic Idea:
You need to use Computed property name concept, to use the expressions for object property names. For that you have to put the expression inside [].
Solution:
You are passing the state variable name in onChange function, so you need to use [] because it will be a variable that will hold some state variable name, then only it will update that state variable.
If you don't use [] then, stateName will be treated as a key (string), it will create a new state variable with name stateName and put the value in that.
Write it like this:
handleChange(stateName, e) {
this.setState({ [stateName]: e.target.value });
}
Check this:
let obj = {b: 5};
let a = 'b';
obj = {...obj, a: 20}; //similar to setState
obj = {...obj, [a]: 1};
console.log(obj);
As mentioned above the Computed property name is the key to this solution. This solution worked well for me.
constructor() {
super(props);
this.state = {tallyPort: '', companyYear: '', interval: '', timeRange: '',
databasePort: '', databaseUserName: '', databasePassword: ''};
this.handleChange = this.handleChange.bind(this);
}
// assigning the name and value is the main objective of this solution.
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
render() {
return(
<div className="dashboard" >
<Input name="tallyPort" onChange={this.handleChange} />
<Input name="companyYear" onChange={this.handleChange} />
<Input name="interval" onChange={this.handleChange} />
<Input name="timeRange" onChange={this.handleChange} />
<Input name="databasePort" onChange={this.handleChange} />
<Input name="databaseUserName" onChange={this.handleChange} />
<Input name="databasePassword" onChange={this.handleChange} />
<Button style={{ width: '200px', marginLeft: '720px'}} onClick={this.handleSave.bind(this)} color="primary">Save</Button>
</div>
);
}
I hope this solution helps. Thanks.

Update data in form. Stay editable. (React with Redux, sans redux-form)

Problem
I have a list of people. I want to:
Select a user to edit by clicking on their name.
Edit that user's information, so I can click the submit button and update the list.
If I click on a different name, I want to switch to that person's information without having to deliberately close the form first.
Everything works until #3. When I click on another person, the form, itself, does NOT update.
My Code
Update Component for the update form:
const UpdateForm = ({ updatePerson, personToUpdate, handleInputChange }) => {
let _name, _city, _age, _id;
const submit = (e) => {
e.preventDefault();
updatePerson({
name: _name.value,
city: _city.value,
age: _age.value,
_id: _id.value
});
};
return (
<div>
<form onSubmit={submit}>
<h3>Update Person</h3>
<label htmlFor="_id">Some Unique ID: </label>
<input type="text" name="_id" ref={input => _id = input} id="_id" defaultValue={personToUpdate._id} onChange={input => handleInputChange(personToUpdate)} required />
<br />
<label htmlFor="name">Name: </label>
<input type="text" name="name" ref={input => _name = input} id="name" defaultValue={personToUpdate.name} onChange={input => handleInputChange(personToUpdate)} />
<br />
<label htmlFor="city">City: </label>
<input type="text" name="city" ref={input => _city = input} id="city" defaultValue={personToUpdate.city} onChange={input => handleInputChange(personToUpdate)} />
<br />
<label htmlFor="age">Age: </label>
<input type="text" name="age" ref={input => _age = input} id="age" defaultValue={personToUpdate.age} onChange={input => handleInputChange(personToUpdate)} />
<br />
<input type="submit" value="Submit" />
</form>
</div>
);
};
export default UpdateForm;
Relevant parts of Person Component:
class Person extends Component {
nameClick() {
if (this.props.person._id !== this.props.personToUpdate._id) {
this.props.setForUpdate(this.props.person);
this.forceUpdate();
}
else {
this.props.toggleUpdatePersonPanel();
}
}
render() {
return (
<div>
<span onClick={this.nameClick}>
{this.props.person.name} ({this.props.person.age})
</span>
</div>
);
}
}
export default Person;
Relevant parts of PeopleList, which holds Persons:
class PeopleList extends Component {
render() {
return(
<div>
{this.props.people.map((person) => {
return <Person
key={person._id}
person={person}
updatePersonPanel={this.props.updatePersonPanel}
setForUpdate={this.props.setForUpdate}
personToUpdate={this.props.personToUpdate}
/>;
})}
</div>
);
}
} // end class
export default PeopleList;
Form Reducer, with just the relevant actions:
export default function formReducer(state = initialState.form, action) {
let filteredPeople;
switch (action.type) {
case TOGGLE_UPDATE_PANEL:
return Object.assign({}, state, { updatePersonPanel: false }, { personToUpdate: {
_id: "",
name: "",
city: "",
age: ""
}});
case SET_FOR_UPDATE:
return Object.assign({}, state, { personToUpdate: action.person }, { updatePersonPanel: true });
case UPDATE_RECORD:
filteredPeople = state.people.filter((person) => {
return person._id === action.person._id ? false : true;
}); // end filter
return Object.assign({}, state, { people: [ ...filteredPeople, action.person] }, { personToUpdate: {
_id: "",
name: "",
city: "",
age: ""
}}, { updatePersonPanel: false });
case HANDLE_INPUT_CHANGE:
return Object.assign({}, state, { personToUpdate: action.person });
default:
return state;
}
}
The relevant parts of my Initial State file:
form: {
people: [
{
_id: "adfpnu64",
name: "Johnny",
city: "Bobville",
age: 22
},
{
_id: "adf2pnu6",
name: "Renee",
city: "Juro",
age: 21
},
{
_id: "ad3fpnu",
name: "Lipstasch",
city: "Bobville",
age: 45
}
],
updatePersonPanel: false,
personToUpdate: {
_id: "",
name: "",
city: "",
age: ""
},
}
Attempts at a Solution( so far)
I have attempted to make the component a completely controlled component, by switching the form attribute to value instead of defaultValue. When I do this, the names switch just fine, but the form becomes unchangeable and useless.
My Questions
Almost all of the solutions to these kind of issues either recommend using redux-form or supply two-way binding solutions that work fine in React without reduce. I want to know how to do this with Redux without using redux-form or anything extra if possible. Is there a way to resolve this without touching lifecycle methods?
Conclusion (For now)
Well, for now, I settled for making my form uncontrolled and used some classic Js DOM methods and a lifecycle method to control the form. For whatever reason, once I employed some of the answer suggestions my browser ate up my CPU and crashed, presumably because there was some kind of infinite loop. If anyone has some further recommendations, I'd really appreciate it. For now I settle for this:
class UpdateForm extends Component {
constructor(props){
super(props);
this.submit = this.submit.bind(this);
}
componentWillReceiveProps(nextProps) {
if (nextProps.personToUpdate._id !== this.props.personToUpdate._id) {
document.getElementById("name").value = nextProps.personToUpdate.name;
document.getElementById("age").value = nextProps.personToUpdate.age;
document.getElementById("city").value = nextProps.personToUpdate.city;
}
}
submit(e) {
e.preventDefault();
this.props.updatePerson({
name: document.getElementById("name").value,
city: document.getElementById("city").value,
age: document.getElementById("age").value,
_id: this.props.personToUpdate._id
});
}
render() {
return (
<div>
<form onSubmit={this.submit}>
<h3>Update Person</h3>
Unique ID: {this.props.personToUpdate._id}
<br />
<label htmlFor="name">Name: </label>
<input type="text" name="name" id="name" ref="name" defaultValue={this.props.personToUpdate.name} required />
<br />
<label htmlFor="city">City: </label>
<input type="text" name="city" id="city" ref="city" defaultValue={this.props.personToUpdate.city} required />
<br />
<label htmlFor="age">Age: </label>
<input type="text" name="age" id="age" ref="age" defaultValue={this.props.personToUpdate.age} required />
<br />
<input type="submit" value="Update" />
</form>
</div>
);
}
} // end class
export default UpdateForm;
I'll be soon exploring redux-form because it is evident that forms as inputs and outputs are a wonky business. For now, my little app works.
Yes there is and you are on the right path. The way is to use value instead of defaultValue but you have to read the value from a state and then use the onChange handler to modify the state.
Something like
this.state = {inputText:''}
Then in the input field
<input value={this.state.inputText} onChange={this.handleChange}/>
And the handleChange function will be
handleChange(event){
this.setState({inputText:event.target.value})
}
Remember to bind the handleChange event in the constructor so you can pass it as this.handleChange in the input field's onChange prop.
Something like this
this.handleChange = this.handleChange.bind(this)
https://facebook.github.io/react/docs/forms.html - Here are the official docs regarding it
Also if you want to do it in redux the same sort of logic applies where this will be the input field
<input value={this.props.inputText} onChange={this.props.handleChange}/>
where inputText and handleChange are redux state and action respectively passed to the component via props
For your case I guess it has to be something like where you are 'reading' values from the people array and the action bound to the onChange modifies that value in the people array in the state.
<--EDIT-->
How it can be done for the case in point. Pass the people in the redux state as a people prop to the component. Pass an action changePeople(newPeople) to the component as a prop which takes an argument newPeople and changes the people in the redux state to have the value newPeople. Since people is nested in form you'll have to do some Object.assign etc to modify the state.
Now in the component using the people props populate the checkboxes using a map function. The map function takes a second parameter index so for each checkbox have a function which sets the local state variable currentPerson to the value of the index
this.props.people.map((person,index) =>
return <Checkbox onClick={()=>this.setState(currentPerson:index)}/>
)
So everytime you click on a checkbox the currentPerson points to the corresponding index.
Now the input fields can be
<input value={this.props.people[this.state.currentPerson].name} onChange={this.handleChange.bind(this,'name')}/>
This is for the 'name' input field. It reads from the currentPerson index of the people array which has been passed down as a prop.
This is how the handleChange will be like
handleChange(property,event){
const newPeople = [
...this.props.people.slice(0, this.state.currentPerson),
Object.assign({}, this.props.people[this.state.currentPerson], {
[property]: event.target.value
}),
...this.props.people.slice(this.state.currentPerson + 1)
]
this.props.changePeople(newPeople)
}
The handleChange takes a property (so you don't have to write separate handlers for each input field). The newPeople basically modifies the element at current index this.state.currentPerson in the people passed from props (ES6 syntax being used here. If you have doubts do ask). Then it is dispatched using the changePeople action which was also passed as props.

How do I edit multiple input controlled components in React?

I have a component that stores a contact object as state - {firstName: "John", lastName: "Doe", phone: "1234567890} I want to create a form to edit this object but if I want the inputs to hold the value of the original contact parameter, I need to make each input a controlled component. However, I don't know how to create a handleChange function that will adjust to each parameter because my state only holds {contact: {...}}. Below is what I currently have -
getInitialState: function () {
return ({contact: {}});
},
handleChange: function (event) {
this.setState({contact: event.target.value });
},
render: function () {
return (
<div>
<input type="text" onChange={this.handleChange} value={this.state.contact.firstName}/>
<input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/>
<input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/>
</div>
);
}
I wish in my handleChange I can do something like
handleChange: function (event) {
this.setState({contact.firstName: event.target.value });
}
There's a "simple" way to do this, and a "smart" way. If you ask me, doing things the smart way is not always the best, because I may be harder to work with later. In this case, both are quite understandable.
Side note: One thing I'd ask you to think about, is do you need to update the contact object, or could you just keep firstName etc. directly on state? Maybe you have a lot of data in the state of the component? If that is the case, it's probably a good idea to separate it into smaller components with narrower responsibilities.
The "simple" way
changeFirstName: function (event) {
const contact = this.state.contact;
contact.firstName = event.target.value;
this.setState({ contact: contact });
},
changeLastName: function (event) {
const contact = this.state.contact;
contact.lastName = event.target.value;
this.setState({ contact: contact });
},
changePhone: function (event) {
const contact = this.state.contact;
contact.phone = event.target.value;
this.setState({ contact: contact });
},
render: function () {
return (
<div>
<input type="text" onChange={this.changeFirstName.bind(this)} value={this.state.contact.firstName}/>
<input type="text" onChange={this.changeLastName.bind(this)} value={this.state.contact.lastName}/>
<input type="text" onChange={this.changePhone.bind(this)} value={this.state.contact.phone}/>
</div>
);
}
The "smart" way
handleChange: function (propertyName, event) {
const contact = this.state.contact;
contact[propertyName] = event.target.value;
this.setState({ contact: contact });
},
render: function () {
return (
<div>
<input type="text" onChange={this.handleChange.bind(this, 'firstName')} value={this.state.contact.firstName}/>
<input type="text" onChange={this.handleChange.bind(this, 'lastName')} value={this.state.contact.lastName}/>
<input type="text" onChange={this.handleChange.bind(this, 'phone')} value={this.state.contact.lastName}/>
</div>
);
}
Update: Same examples using ES2015+
This section contains the same examples as shown above, but using features from ES2015+.
To support the following features across browsers you need to transpile your code with Babel using e.g.
the presets es2015 and react,
and the plugin stage-0.
Below are updated examples, using object destructuring to get the contact from the state,
spread operator to
create an updated contact object instead of mutating the existing one,
creating components as Classes by
extending React.Component,
and using arrow funtions to
create callbacks so we don't have to bind(this).
The "simple" way, ES2015+
class ContactEdit extends React.Component {
changeFirstName = (event) => {
const { contact } = this.state;
const newContact = {
...contact,
firstName: event.target.value
};
this.setState({ contact: newContact });
}
changeLastName = (event) => {
const { contact } = this.state;
const newContact = {
...contact,
lastName: event.target.value
};
this.setState({ contact: newContact });
}
changePhone = (event) => {
const { contact } = this.state;
const newContact = {
...contact,
phone: event.target.value
};
this.setState({ contact: newContact });
}
render() {
return (
<div>
<input type="text" onChange={this.changeFirstName} value={this.state.contact.firstName}/>
<input type="text" onChange={this.changeLastName} value={this.state.contact.lastName}/>
<input type="text" onChange={this.changePhone} value={this.state.contact.phone}/>
</div>
);
}
}
The "smart" way, ES2015+
Note that handleChangeFor is a curried function:
Calling it with a propertyName creates a callback function which, when called, updates [propertyName] of the
(new) contact object in the state.
class ContactEdit extends React.Component {
handleChangeFor = (propertyName) => (event) => {
const { contact } = this.state;
const newContact = {
...contact,
[propertyName]: event.target.value
};
this.setState({ contact: newContact });
}
render() {
return (
<div>
<input type="text" onChange={this.handleChangeFor('firstName')} value={this.state.contact.firstName}/>
<input type="text" onChange={this.handleChangeFor('lastName')} value={this.state.contact.lastName}/>
<input type="text" onChange={this.handleChangeFor('phone')} value={this.state.contact.lastName}/>
</div>
);
}
}
ES6 one liner approach
<input type="text"
value={this.state.username}
onChange={(e) => this.setState({ username: e.target.value })}
id="username"/>
The neatest approach
Here is an approach that I used in my simple application. This is the recommended approach in React and it is really neat and clean. It is very close to ArneHugo's answer and I thank hm too. The idea is a mix of that and react forms site.
We can use name attribute of each form input to get the specific propertyName and update the state based on that. This is my code in ES6 for the above example:
class ContactEdit extends React.Component {
handleChangeFor = (event) => {
const name = event.target.name;
const value = event.target.value;
const { contact } = this.state;
const newContact = {
...contact,
[name]: value
};
this.setState({ contact: newContact });
}
render() {
return (
<div>
<input type="text" name="firstName" onChange={this.handleChangeFor} />
<input type="text" name="lastName" onChange={this.handleChangeFor}/>
<input type="text" name="phone" onChange={this.handleChangeFor}/>
</div>
);
}
}
The differences:
We don't need to assign state as value attribute. No value is needed
The onChange method does not need to have any argument inside the function call as we use name attribute instead
We declare name and value of each input in the begening and use them to set the state properly in the code and we use rackets for name as it is an attribute.
We have less code here and vey smart way to get any kind input from the form because the name attribute will have a unique value for each input.
See a working example I have in CodPen for my experimental blog application in its early stage.
There are two ways to update the state of a nested object:
Use JSON.parse(JSON.stringify(object)) to create a copy of the object, then update the copy and pass it to setState.
Use the immutability helpers in react-addons, which is the recommended way.
You can see how it works in this JS Fiddle. The code is also below:
var Component = React.createClass({
getInitialState: function () {
return ({contact: {firstName: "first", lastName: "last", phone: "1244125"}});
},
handleChange: function (key,event) {
console.log(key,event.target.value);
//way 1
//var updatedContact = JSON.parse(JSON.stringify(this.state.contact));
//updatedContact[key] = event.target.value;
//way 2 (Recommended)
var updatedContact = React.addons.update(this.state.contact, {
[key] : {$set: event.target.value}
});
this.setState({contact: updatedContact});
},
render: function () {
return (
<div>
<input type="text" onChange={this.handleChange.bind(this,"firstName")} value={this.state.contact.firstName}/>
<input type="text" onChange={this.handleChange.bind(this,"lastName")} value={this.state.contact.lastName}/>
<input type="text" onChange={this.handleChange.bind(this,"phone")} value={this.state.contact.phone}/>
</div>
);
}
});
ReactDOM.render(
<Component />,
document.getElementById('container')
);
Here is generic one;
handleChange = (input) => (event) => {
this.setState({
...this.state,
[input]: event.target.value
});
}
And use like this;
<input handleChange ={this.handleChange("phone")} value={this.state.phone}/>
<input> elements often have a property called name.
We can access this name property from the event object that we receive from an event handler:
Write a generalized change handler
constructor () {
super();
this.state = {
name: '',
age: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange (evt) {
this.setState({ [evt.target.name]: evt.target.value });
}
render () {
return (
<form>
<label>Name</label>
<input type="text" name="name" onChange={this.handleChange} />
<label>Age</label>
<input type="text" name="age" onChange={this.handleChange} />
</form>
);
}
source
updatePrevData=(event)=>{
let eventName=event.target.name;
this.setState({
...this.state,
prev_data:{
...this.state.prev_data,
[eventName]:event.target.value
}
})
console.log(this.state)
}
You can do it without duplicate code and easy way
handleChange=(e)=>{
this.setState({
[e.target.id]:e.target.value
})
}
<Form.Control type="text" defaultValue={this.props.allClients.name} id="clientName" onChange={this.handleChange}></Form.Control>
<Form.Control type="email" defaultValue={this.props.allClients.email} id="clientEmail" onChange={this.handleChange}></Form.Control>
handleChange(event){
this.setState({[event.target.name]:event.target.value});
this.setState({[event.target.name]:event.target.value});
}

Categories

Resources