2
votes

Réagir, mettre à jour une valeur unique dans l'état constitué d'un tableau d'objets

J'essaye de mettre à jour une seule valeur dans l'état, voici mon état:

const course = this.state.courses[index];
this.setState({
  courses: [...this.state.courses, course.courseGrade: courseGrade]
})

J'ai la valeur que je veux mettre à jour et l'index de l'objet à l'intérieur du tableau mais je ne trouve pas de moyen de mettre à jour la valeur ... Voici ce que j'ai jusqu'à présent:

  updateCourseGrade(courseGrade, id){
        const index = this.state.courses.findIndex(course => (
          id === course.id
        ));



    const courses = [...this.state.courses];
    courses[index].courseGrade = courseGrade;
    this.setState({courses});
  }

aussi j'ai pensé que j'ai essayé ce bloc

state = {
    courses: [
      {
        id: 1,
        courseName: 'lenguage',
        courseType: false,
        courseHours: 10,
        courseGrade: ''
      },{
        id: 2,
        courseName: 'Math',
        courseType: true,
        courseHours: 20,
        courseGrade: ''
      },{
        id: 3,
        courseName: 'Biology',
        courseType: false,
        courseHours: 30,
        courseGrade: ''
      }
    ]
  };

toute aide serait incroyable tnx!


0 commentaires

4 Réponses :


0
votes

vous ne pouvez pas changer les variables const,

let state = {...this.state}

state.courses[INDEX].courseGrade = courseGrade;

this.setState({...state})

si vous avez la valeur et l'index de vos données dans le tableau, faites-le simplement

const courses = [...this.state.courses];
    courses[index].courseGrade = courseGrade;
    this.setState({courses});

j'espère que cela sera utile


3 commentaires

Pourquoi cela fonctionnerait-il? Veuillez expliquer quel était le problème et pourquoi cela fonctionnera


Bon début de solution! Mais attention, il s'agit d'un changement en mutation et doit être évité si possible.


vous pouvez certainement les changer , la seule chose que const empêche est la réaffectation. Cela ne vaut rien non plus que l'opération de propagation ne concerne que des clones peu profonds, de sorte que le tableau des cours et chaque cours individuel sont toujours passés par référence et mutés ici. Il serait préférable d'utiliser this.state.slice ()



2
votes

Lorsque vous travaillez avec l'état React, vous travaillez avec une structure de données immuable Immutable.js peut être une bouée de sauvetage.

Mais nous pouvons aussi le faire sans dépendances avec la répartition des cartes et des objets:

this.setState({
    courses: this.state.courses.map(course => course.id === id ? { ...course, courseGrade } : course)
})


5 commentaires

Vous ne devez pas non plus utiliser l'état directement pour le mapper. Mauvaise pratique.


@SubhenduKundu c'est en fait correct de le faire de cette façon. La fonction de carte sur un tableau crée un nouveau tableau, c'est donc jusqu'à présent la seule solution non mutante, bien qu'un peu difficile à suivre pour les nouveaux développeurs :)


@SubhenduKundu yup de préférence, vous pouvez également utiliser la forme de setState qui reçoit une fonction au lieu d'un objet de mise à jour, mais je pense que ce n'est nécessaire que pour la rare occasion de condition de course possible - comme lors du basculement des choses


ce n'est pas "obligatoire" en soi, mais vous avez raison en ce que le plus grand avantage de passer une fonction à set state est que vos appels à setState se feront de manière synchrone reactjs.org/docs/...


Oui, vous avez raison, mais vous voudrez peut-être regarder codereview.stackexchange.com/ questions / 160411 /… il y a aussi quelques articles sur ce pourquoi vous ne devriez pas utiliser le state.map directement. Je vous mettrai à jour dès que j'aurai mis la main sur mon ordinateur portable.



3
votes

Idéalement, vous devriez utiliser ce

this.setState((prevState) => {
// Use prevState and do the map just like someone suggested in one of the answer
 courses: prevState.map(course => course.id === id ? {...course, courseGrade } : course)
})


1 commentaires

Un problème de modification est survenu. Dans le bus, répondre par téléphone 🙈 j'espère que vous comprenez.



1
votes

Généralement, lorsque vous travaillez avec un état, vous souhaitez effectuer uniquement des opérations pures, car la mutation d'un état peut conduire à des bogues déroutants et difficiles à localiser.

updateCourseGrade = (courseGrade, id) => {
  this.setState((
    produce(draftState => {
      const index = draftState.courses.findIndex(course => (
        id === course.id
      ));
      draftState.courses[index].courseGrade = courseGrade;
    })
  ))
}

Cela peut devenir assez fastidieux, mais c'est essentiel à la philosophie de React lui-même. Si vous voulez vous faciliter la tâche, je vous recommande de consulter immer , une bibliothèque NPM qui exporte une fonction , produire. Je ne recommande généralement pas les bibliothèques tierces comme solutions, mais j'aime particulièrement immer. Cela aura l'air bizarre au début, mais cela fonctionne en utilisant quelque chose appelé Proxy (une nouvelle fonctionnalité de langage dans ES6):

updateCourseGrade = (courseGrade, id) => {
  const course = this.state.courses.find(course => course.id === id);
  if (course) {
    const updatedCourse = { ...course, courseGrade };
    const updatedCourses = this.state.courses
      .filter(course => course.id !== id)
      .concat(updatedCourse);
    this.setState({ courses: updatedCourses });
  }
}

Souvent, immer n'est pas nécessaire, mais lorsque vous travaillez avec tableaux d'objets et en particulier avec des structures d'objets imbriquées, cela peut être une aubaine pour vous aider à écrire du code propre qui fonctionne bien.


0 commentaires