Reputation: 1346
Here's my fiddle
https://codepen.io/seunlanlege/pen/XjvgPJ?editors=0011
I have two inputs and I'm trying to use one method to handle the onChange
event for any input field.
I've torn the internet apart looking for a solution but came up with nothing.
I'm using es6 please how do I go about this?
class Form extends React.Component {
`constructor(props) {
super(props);
this.state = {text:{
e:'hi',
c:''
}};
this.handleSubmit = this.handleSubmit.bind(this);
}`
`handleChange(event,property) {
const text = this.state.text;
text[property] = event.target.value;
this.setState({text});
}`
`handleSubmit(event) {
alert('Text field value is: ' + this.state.text.e);
}`
`render() {
return (
<div>
<div>{this.state.text.e}</div>
<input type="text"
placeholder="Hello!"
value={this.state.text.e}
onChange={this.handleChange.bind(this)} />
<input type="text"
placeholder="Hello!"
value={this.state.text.c}
onChange={this.handleChange.bind(this)} />
<button onClick={this.handleSubmit}>
Submit
</button>
</div>
);
}
}`
ReactDOM.render(
`<Form />`,
document.getElementById('root')
);
Upvotes: 2
Views: 1824
Reputation: 281626
You have not passed the propert to the handeChange function. pass it like this.handleChange.bind(this, 'e')
and also the order of receiving props is wrong, property will be the first argument and then the event and not the reverse.
Code:
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {text:{
e:'hi',
c:''
}};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(property, event) {
console.log(event.target.value);
const text = {...this.state.text};
text[property] = event.target.value;
this.setState({ text }); //or you can use the shorthand here. ES6 is awesome <3
}
handleSubmit(event) {
alert('Text field value is: ' + this.state.text.e);
}
render() {
return (
<div>
<div>{this.state.text.e}</div>
<div>{this.state.text.c}</div>
<input type="text"
placeholder="Hello!"
value={this.state.text.e}
onChange={this.handleChange.bind(this, 'e')} />
<input type="text"
placeholder="Hello!"
value={this.state.text.c}
onChange={this.handleChange.bind(this, 'c')} />
<button onClick={this.handleSubmit}>
Submit
</button>
</div>
);
}
}
ReactDOM.render(
<Form />,
document.getElementById('root')
);
Upvotes: 3
Reputation: 18546
One way to do this would be to give each of your inputs a name
attribute and set the state based on that:
class Form extends React.Component {
constructor(props) {
super(props);
this.state = { text: {
e: 'hi',
c: ''
} };
this.onChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
var oldState = this.state.text;
var newState = { [e.target.name]: e.target.value };
// I have to assign/join because you've put the text state in a parent object.
this.setState({ text: Object.assign(oldState, newState) });
}
handleSubmit(event) {
alert('Text field value is: ' + this.state.text.e);
}
render() {
console.log(this.state);
return (
<div>
<div>{this.state.text.e}</div>
<input type="text"
placeholder="Hello!"
name="e"
value={this.state.text.e}
onChange={this.onChange} />
<input type="text"
placeholder="Hello!"
name="c"
value={this.state.text.c}
onChange={this.onChange} />
<button onClick={this.handleSubmit}>
Submit
</button>
</div>
);
}
}
ReactDOM.render(
<Form />,
document.getElementById('View')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.min.js"></script>
<div id="View"></div>
Also, there are so-called two-way binding helpers. As I understand they still show mixins in React's documentation, so you are probably better off with third party libraries like react-link-state
:
this.state = {
username: '',
password: '',
toggle: false
};
<input type="text" valueLink={linkState(this, 'username')} />
<input type="password" valueLink={linkState(this, 'password')} />
<input type="checkbox" checkedLink={linkState(this, 'toggle')} />
Upvotes: 2