Reputation: 2587
I have multiple text input fields and a single checkbox. Whenever I check the checkbox, I want to clear one of my text input fields. I looked at various answers for this, however, none of them worked.
Here is my code:
import React, { Component } from 'react';
class Form extends Component {
state = {}
constructor(props) {
super(props);
this.state = {
text1: "",
text2: ""
};
this.handleChange = this.handleChange.bind(this);
this.handleClear = this.handleClear.bind(this);
}
handleChange(event) {
let name = event.target.name;
let value = event.target.value;
this.setState({[name]: value});
}
handleClear(event){
let checked = event.target.checked;
if(checked){
this.setState({"text2": ''}); // did not work
// how to do it???
console.log(this.state)
}
}
render() {
return (
<form>
<input type="text" name="text1" onChange={this.handleChange}/>
<input type="text" name="text2" onChange={this.handleChange}/>
<input type="checkbox" name="clear-text2" onChange={this.handleClear}/>
</form>
);
}
}
export default Form;
In this code, I want the field text2
to get cleared when the checkbox is checked.
Upvotes: 2
Views: 1608
Reputation: 4195
Try this somthing like this,
<input type="text" name="text1" onChange={this.handleChange} value={this.state.text1} />
<input type="text" name="text2" onChange={this.handleChange} value={this.state.text2} />
You are not passing the state
value to input elements. So, value
defaults to null
So React is letting you mod that input. And your mistakenly thinking your state has control of the input value.
Upvotes: 3
Reputation: 39320
Your text inputs are not controlled components, they have an onChange but you did not set a value property:
class Form extends React.Component {
state = {};
constructor(props) {
super(props);
this.state = {
text1: '',
text2: '',
};
//remove bind, using arrow functions will bind
}
handleChange = (event) => {//arrow function
let name = event.target.name;
let value = event.target.value;
this.setState({ [name]: value });
};
handleClear = (event) => {//arrow function
let checked = event.target.checked;
if (checked) {
this.setState({ text2: '' }, () =>
//log in the setState callback gets the current state
// you do not want to nest this too much, you already
// know the state because you just set it so there is
// usually no need for this
console.log('works:', this.state)
);
console.log('does not work', this.state);
}
};
render() {
return (
<form>
<input
type="text"
name="text1"
value={this.state.text1}
onChange={this.handleChange}
/>
<input
type="text"
name="text2"
// added value property to text2
value={this.state.text2}
onChange={this.handleChange}
/>
<input
type="checkbox"
name="clear-text2"
onChange={this.handleClear}
/>
</form>
);
}
}
ReactDOM.render(<Form />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
here is a functional component example:
const Form = () => {
//using useState to set state
const [state, setState] = React.useState({
text1: '',
text2: '',
});
//using useCallback for event handlers
const handleChange = React.useCallback((event) => {
let name = event.target.name;
let value = event.target.value;
//pass callback to setState to get current state
// and copying state to new state
setState((state) => ({ ...state, [name]: value }));
}, []);
const handleClear = React.useCallback((event) => {
let checked = event.target.checked;
if (checked) {
setState((state) => {
const newState = { ...state, text2: '' };
console.log('works', newState);
return newState;
});
//logging a stale closure will not work
// and only creates needless dependency
// console.log('does not work', state);
}
}, []);
//no this in jsx
return (
<form>
<input
type="text"
name="text1"
onChange={handleChange}
/>
<input
type="text"
name="text2"
// added value property to text2
value={state.text2}
onChange={handleChange}
/>
<input
type="checkbox"
name="clear-text2"
onChange={handleClear}
/>
</form>
);
};
ReactDOM.render(<Form />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 4