Search code examples
javascriptreactjsformscheckboxsetstate

React state with value of array, for multi checkbox values, mutate outside and after setState() to number


I'm new in react so excuse me if I looked repetitive but i couldn't find an answer online.
I'm working on react multi value checkbox form by pushing the checked value inside stat array, it's seem working well inside the setState function with first checked, when logged it in the console I received an array whit the new added value.
but directly after the setState() the array value changed to 1 !! and of curse I can't use any high-order functions anymore.
So any idea why that's happen, and how I can fix it ?!
Please find screenshot of the code

import React, { Component } from 'react';

class Test extends Component {
  constructor(props) {
    super(props);
    this.state = {
      nationality: [],
    };
    this.handelChecked = this.handelChecked.bind(this);
  }

  handelChecked(e) {
    let { name, value, checked } = e.target;
    console.log(name, value, checked);
    console.log(this.state.nationality);
    if (checked) {
      this.setState({
        nationality: this.state.nationality.push(value),
      });
    }
    console.log(this.state.nationality);
  }
  render() {
    console.log(this.state.nationality);

    return (
      <>
        <form>
          <label>Nationality</label>
          <br />
          <label>
            <input
              type='checkbox'
              name='nationality'
              value='Japaneses'
              onChange={this.handelChecked}
            />
            Japaneses
          </label>
          <br />
          <label>
            <input
              type='checkbox'
              name='nationality'
              value='Dutch'
              onChange={this.handelChecked}
            />
            Dutch
          </label>
          <br />
          <label>
            <input
              type='checkbox'
              name='nationality'
              value='Egyptian'
              onChange={this.handelChecked}
            />
            Egyptian
          </label>
        </form>
        <div>
          <br />
          <h4>Nationality:</h4>
          <p>{this.state.nationality}</p>
        </div>
      </>
    );
  }
}

export default Test;


Solution

  • Hi Please check the example below. I used setState with prevState, that is the main change for working the code. I also do one optional change that is, I removed this.handelChecked = this.handelChecked.bind(this); from constructor and use arrow function.

    import React, {Component} from 'react';
    
    class Test extends Component {
        constructor(props) {
            super(props);
            this.state = {
                nationality: [],
            };
        }
    
        handelChecked = (e) => {
            let {name, value, checked} = e.target;
            console.log(this.state.nationality);
            if (checked) {
                this.setState(prevState => {
                    prevState.nationality.push(value);
                    return{
                        nationality: prevState.nationality
                    }
                });
            }
            console.log(this.state.nationality);
        };
    
        render() {
            return (
                <>
                    <form>
                        <label>Nationality</label>
                        <br/>
                        <label>
                            <input
                                type='checkbox'
                                name='nationality'
                                value='Japaneses'
                                onChange={this.handelChecked}
                            />
                            Japaneses
                        </label>
                        <br/>
                        <label>
                            <input
                                type='checkbox'
                                name='nationality'
                                value='Dutch'
                                onChange={this.handelChecked}
                            />
                            Dutch
                        </label>
                        <br/>
                        <label>
                            <input
                                type='checkbox'
                                name='nationality'
                                value='Egyptian'
                                onChange={this.handelChecked}
                            />
                            Egyptian
                        </label>
                    </form>
                    <div>
                        <br/>
                        <h4>Nationality:</h4>
                        <p>{this.state.nationality}</p>
                    </div>
                </>
            );
        }
    }
    
    export default Test;