Phenomenal One
Phenomenal One

Reputation: 2587

Clear a text input whenever a checkbox is checked in reactjs

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

Answers (2)

ezio4df
ezio4df

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

HMR
HMR

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

Related Questions