0

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;

3
  • 1
    1) Please post code as text, not images. 2) You're mutating state by calling this.state.nationality.push(). 3) State updates are async, so even if it updated correctly, the console.log immediately after the update will not have the updated value available. Commented May 20, 2020 at 19:05
  • 1
    push returns a number. And please post code as code, not as a picture - let alone a link to a picture. Commented May 20, 2020 at 19:05
  • Ok, thanks guys, it's seem a compeletly wrong approach Commented May 20, 2020 at 19:30

2 Answers 2

1

I fix the handelChecked() as following:

handelChecked(e) {
let { name, value, checked } = e.target;
if (checked) {
  this.setState({
    nationality: [...this.state.nationality, value],
  });
}
Sign up to request clarification or add additional context in comments.

Comments

0

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;

5 Comments

thanks Khabir, it's work but duplicating the value, i got [Dutch, Dutch, Egyptian, Egyptian], I fix it as following nationality: [...this.state.nationality, value],
handelChecked(e) { let { name, value, checked } = e.target; if (checked) { this.setState({ nationality: [...this.state.nationality, value], }); } }
@Alaa, Why you did undo for Answer? Is there anything wrong?
I didn't. I maybe by mistake
Oh no problem, I thought I had something wrong in my code. Thank you so much

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.