Home javascript setState does not work

setState does not work

Author

Date

Category

I am learning React.js. I have a form to add components to a page. I am doing this form validation. When you click on the Add button, the onBtnClickHandler () function is triggered, which receives values ​​from the form inputs and updates the state.
In each input, I have a name attribute, the value of this attribute becomes a key, value from the input becomes a value, this all goes to my new state. The form works well.
Next, using the validate () function, I check if anything has been entered into the input and update the state. To do this, I have an objectItems object, where I write the state of my input, nameMyInputIsValid: true or false. Everything works too.
I also have a formIsValid property in objectItems, which is false by default. In the validateData () function, I check that this.state.objectItems value of all the nameMyInputIsValid is true and I want to update the state to rewrite formIsValid: true. But the state is not updated, and I don’t understand why.

import React, {Component} from 'react';
import Card from './Card';
import apiCall from '../../Api/mockedApi';
import CardsGenerator from './CardsGenerator';
class CardsContainer extends Component {
 constructor (props) {
  super (props);
  this.state = {
   error: null,
   isLoaded: false,
   items: [],
   objectItems: {
    genderIsValid: false,
    priceIsValid: false,
    titleIsValid: false,
    imageUrlIsValid: false,
    formIsValid: false,
   },
  };
  this.deleteCard = this.deleteCard.bind (this);
  this.onChangeInput = this.onChangeInput.bind (this);
  this.onBtnClickHandler = this.onBtnClickHandler.bind (this);
  this.validate = this.validate.bind (this);
  this.validateData = this.validateData.bind (this);
 }
 componentDidMount () {
  apiCall (). then (
   (result) = & gt; {
    this.setState ({
     isLoaded: true,
     items: result,
    });
   },
   (error) = & gt; {
    this.setState ({
     isLoaded: true,
     error,
    });
   },
  );
 }
 onChangeInput (event) {
  const {name} = event.currentTarget;
  const {value} = event.currentTarget;
  this.setState (state = & gt; ({objectItems: {... state.objectItems, [name]: value, [`$ {name} IsValid`]: this.validate (value)}}));
 }
 onBtnClickHandler (e) {
  e.preventDefault ();
  this.setState (state = & gt; ({items: [... state.items, state.objectItems]}));
  console.log (this.state.objectItems);
  this.validateData ();
 }
 validate (value) {
  if (typeof value === 'string') {
   return value.length & gt; 2;
  } if (typeof value === 'number') {
   return value & gt; = 0;
  }
  return value;
 }
 validateData () {
  const {
   genderIsValid, priceIsValid, titleIsValid, imageUrlIsValid, formIsValid,
  } = this.state.objectItems;
  if (genderIsValid === true & amp; & amp; priceIsValid === true & amp; & amp; titleIsValid & amp; & amp; imageUrlIsValid === true) {
   this.setState (() = & gt; ({objectItems: {formIsValid: true}}));
   // this.setState ({objectItems: {formIsValid: true}})
  }
  console.log (genderIsValid, priceIsValid, titleIsValid, imageUrlIsValid, formIsValid);
 }
 deleteCard (e, index) {
  e.preventDefault ();
  const {items} = this.state;
  const newItems = items.filter ((item, i) = & gt; i! == index);
  this.setState (() = & gt; ({
   items: newItems,
  }));
 }
 render () {
  const {error, isLoaded, items} = this.state;
  const itemColorBorder = () = & gt; this.state.objectItems.map (
   (item, index, arr) = & gt; (item === true? 'green': 'red'),
  );
  if (error) {
   return & lt; div & gt; No cards yet & lt; / div & gt ;;
  } if (! isLoaded) {
   return & lt; div & gt; Loading ... & lt; / div & gt ;;
  }
  return (
   & lt; React.Fragment & gt;
    {items.map (
     (item, index) = & gt; & lt; Card info = {item} index = {index} del = {this.deleteCard} / & gt ;,
    )} 
& Lt; CardsGenerator id = "cardGenerateForm" key = {9379992} add = {this.onChangeInput} submit = {this.onBtnClickHandler} borderColor = {itemColorBorder} disabled = {this.state.objectItems.formIsValid} validate = {this.validate} / & gt;
   & lt; /react.fragment>
  );
 }
}
Export Default Cardscontainer;

Answer 1, Authority 100%

code in style

this.setstate ({value});
Console.log (this.state.value);

will not give the desired result, because setstate () is an asynchronous operation.

In order to perform some kind of code after setting the component status, you can transfer the Callback by the second parameter:

this.setstate ({value}, () = & gt; {
 // here State is already in the right state
 Console.log (this.state.value);
});

In the case of code from your example, it will be something like this:

this.setstate (state = & gt; ({items: [... state.items, state.ObjectItems] }), () = & gt; {
  Console.log (this.state.ObjectItems);
  this.validatedata ();
});

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions