0
votes

Réagir dans l'état de mise à jour tardive

Ce que j'essaie de faire est de mettre à jour un tableau en état d'ajout d'une chaîne du nom du bouton L'utilisateur appuyé. L'utilisateur a plusieurs boutons, donc après avoir appuyé sur eux tout ce que je devais être laissé avec un tableau de chaînes en corrélation sur le bouton de l'utilisateur.

Tout d'abord, je donne à l'utilisateur une alerte qui leur dit que la nourriture a été ajoutée puis je tente simplement d'ajouter le nom de cet aliment à la matrice en état. Après quoi je passe ce tableau vers le composant parent pour mettre à jour un tableau similaire là-bas. P>

Le problème que je reçois est que lorsque j'appuie sur l'une des options de nourriture, le tableau en état ne met pas à jour, mais Je reçois la bonne alerte. Lorsque j'essaie une deuxième aliment, la matrice dans les mises à jour de l'état avec la première option que j'ai sélectionnée. À partir de là, à chaque fois que j'essaie d'ajouter un aliment de nourriture la matrice dans les mises à jour de l'état avec les aliments que j'ai sélectionnés avant cela. P>

Je crois que je suis que je me mettais à la mise à jour de l'état de la réaction imminemment. Je sais que les mises à jour de l'état ne sont pas garanties dans la réaction. P>

Désolé pour le long post, merci pour votre temps. P>

import React from "react";
import "./style.scss";
import FoodData from "./foodData.json";

class Food extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      foodData: [],
      addedFoods: []
    };
    this.handleClick = this.handleClick.bind(this);
  }

  componentDidMount() {
    // Build a new array of objects from FoodData
    const newFoodData = FoodData.map(
      ({ name, pic, serving, calories, sugar, protien }, index) => ({
        id: index,
        name,
        pic,
        serving,
        calories,
        sugar,
        protien
      })
    );
    // Assign the new object to state
    this.setState({ foodData: newFoodData });
  }

  handleClick(e) {
    alert("Added " + e.target.name);
    this.setState(
      {
        addedFoods: [...this.state.addedFoods, e.target.name]
      },
      this.props.updateAddedFoods(this.state.addedFoods)
    );
  }

  render() {
    const displayFood = () => {
      let foodItems = []; // Crate an array
      for (let i = 0; i < this.state.foodData.length; i++) {
        foodItems.push(
          // push item to array through the loop
          <div className="food-card" key={i}>
            <img src={require(`${this.state.foodData[i].pic}`)} />
            <ul>
              <li>{this.state.foodData[i].name}</li>
              <li>Serving: {this.state.foodData[i].serving}</li>
              <li>Calories: {this.state.foodData[i].calories}</li>
              <li>Sugar: {this.state.foodData[i].sugar}</li>
              <li>Protien: {this.state.foodData[i].protien}</li>
            </ul>
            <button
              onClick={this.handleClick}
              name={this.state.foodData[i].name}
            >
              Add
            </button>
          </div>
        );
      }
      return foodItems;
    };

    return (
      <div>
        <div className="food-container">
          {!this.state.foodData.length ? <h1>Loading ...</h1> : displayFood()}
        </div>
      </div>
    );
  }
}

export default Food;


4 commentaires

Bonjour! Juste pour être sûr .. Je vois que dans Handleclick (E) Vous exécutez un rappel this.props.updaTaNeadDsDs . Pourriez-vous s'il vous plaît, dans ce rappel, ajouter un console.log (this.state.addedfoods) ? Juste pour voir si l'état est passé à cette fonction est déjà mis à jour ou non, car le problème pourrait être de la manière dont vous mettez à jour l'état dans Handleclick


Bien sûr, je vais lui donner un coup maintenant ... et j'ai exactement la même chose. Première fois que j'essaie d'ajouter un élément de nourriture Le journal de la console imprime un tableau vide qui devrait avoir une nourriture juste ajoutée. Ensuite, lorsque j'essaie d'ajouter un autre aliment, le journal de la console imprime un tableau avec un élément, celui que j'ai essayé d'ajouter en premier.


UHM OK, j'ajoute une réponse avec un exemple, laissez-moi savoir si cela aide


Merci de m'aider mais ça marche. Je l'apprécie cependant. Si je pouvais vous voter, je le ferais.


3 Réponses :


1
votes

second argument pour SetState code> doit être une fonction et non un appel de la fonction. Il vaut également mieux utiliser setstate (OldState => Newstate) CODE> Lorsque le nouvel état est basé sur l'ancien:

  handleClick(e) {
    const name = e.target.name;
    alert("Added " + name);
    this.setState(oldState => ({
        addedFoods: [...oldState.addedFoods, name]
      }),
      () => this.props.updateAddedFoods(this.state.addedFoods)
    );
  }


5 commentaires

Merci pour l'entrée et désolé pour la longue réponse, j'essaye maintenant ... quand je fais le changement, je reçois une erreur "TypeError: impossible de lire la propriété" Nom "de NULL". Essayer de difficulté à tirer maintenant, mais vous avez raison à propos de l'état.


Essayez de supprimer alerte ou enregistrement e.target.name avant de cela. Réagir réutilise les objets d'événement et il pourrait être nettoyé avant SetState


Obtenir toujours la même erreur sur le "ajoutéFood: [... oldstate.addedfoods, e.target.name]" Ligne avec ou sans l'alerte.


J'ai mis à jour ma réponse. L'objet événement stocké dans E est effacé avant d'atteindre le rappel de l'intérieur SETState .


Yeeet vous avez eu mon homme. J'aurais aimé pouvoir voter votre réponse. Merci un tas



0
votes

setState est asynchrone, donc lorsque vous passez this.state.addedfoods comme argument sur ceci.props.updatedaddeds Vous passez l'état avant de le changer. Comme il semble que vous siez des données de duplication, puis-je suggérer que seul le parent a la gamme de nourriture et la passe comme un accessoire à l'enfant?


1 commentaires

C'est un très bon changement de conception que je devrais vous faire totalement droit et je le ferai maintenant.



0
votes

Alors, comme je l'ai dit dans le commentaire, je pense que handleclick () est le problème, plus exactement comment vous mettez à jour l'état.
Pouvez-vous essayer d'écrire cette fonction comme suit: xxx

Cependant, @iArz est totalement correct: il semble que vous ayez les mêmes données à la fois dans le composant parent et composant des enfants. Gardez-le dans la composante parent et transmettez-le aux enfants les données et à une fonction pour la mettre à jour.


1 commentaires

100% raison sur les doublons de données dans les parents et les enfants. Douleurs de croissance lol. Merci pour tous les conseils.