web-dev-qa-db-fra.com

Faire une boucle sur une carte dans React

J'ai un objet Map:

let dateJobMap = new Map();

for (let jobInArray of this.state.jobs) {
  let deliveryDate: Date = new Date(jobInArray.DeliveryDate);
  let deliveryDateString: string = deliveryDate.toLocaleDateString("en-US");

  if (dateJobMap.has(deliveryDateString)) {
    let jobsForDate: IDeliveryJob[] = dateJobMap.get(deliveryDateString);
    jobsForDate.Push(jobInArray);
  }
  else {
    let jobsForDate: IDeliveryJob[] = [jobInArray];
    dateJobMap.set(deliveryDateString, jobsForDate);
  }
}

Dans ma méthode render, je veux appeler un objet TruckJobComp pour chaque travail de livraison dans le tableau de la valeur pour l'afficher:

        <div className={ styles.column }>
          <p className={ styles.description }>{escape(this.props.description)}</p>

          {
            dateJobMap.forEach(function(jobsForDate, dateString) {
              jobsForDate.map(job => (
                <TruckJobComp job = { job } />
              ))
            })
          }
        </div>

Cela semble fonctionner mais ne fonctionne pas. Il ne crée jamais un TruckJobComp. Je fais un .forEach itération sur mon Map, et pour chaque value's array, j'utilise .map pour obtenir l'objet de travail individuel à envoyer à l'objet TruckJobComp.

Lorsque je crée un temp array pour récupérer les travaux de la dernière boucle:

let tempJobs: IDeliveryJob[];

et dans la boucle ajoutez:

  if (dateJobMap.has(deliveryDateString)) {
    let jobsForDate: IDeliveryJob[] = dateJobMap.get(deliveryDateString);
    jobsForDate.Push(jobInArray);

    tempJobs = jobsForDate;
  }

puis utilisez ce array dans le rendu:

          <div className={ styles.column }>
            <p className={ styles.description }>{escape(this.props.description)}</p>
            {
              tempJobs.map(job => (
                <TruckJobComp job = { job }/>
              ))
            }
          </div>

Il s'affiche comme prévu.

J'ai des avertissements dans Visual Studio Code:

Warning - tslint - ...\TruckDeliverySchedule.tsx(104,38): error no-function-expression: Use arrow function instead of function expression

Je n'en sais pas assez pour comprendre. La ligne 104 correspond à:

dateJobMap.forEach(function(jobsForDate, dateString) {

Je suis très nouveau dans ce domaine, donc je ne suis pas sûr à 100% de la façon dont cela fonctionne. J'essaye juste de rassembler les morceaux que j'ai appris pour que les choses fonctionnent.

Deuxième édition:

{escape (this.props.description)}

{
  [...dateJobMap.keys()].map(jobsForDate => // line 154
    jobsForDate.map(job => (
      <TruckJobComp job = { job } />
    ))
  )
}

Produit une erreur:

[09:06:56] Error - TypeScript - src\...\TruckDeliverySchedule.tsx(154,27): error TS2461: Type 'IterableIterator<any>' is not an array type.
5
Holden1515

Tout cet avertissement veut dire qu'au lieu d'utiliser la syntaxe function(jobsForDate, dateString) {}, vous devez utiliser la syntaxe (jobsForDate, dateString) => {}.

La raison pourrait être la façon dont this est délimité dans les fonctions fléchées par rapport aux expressions de fonction. Voir ce post.

Ma conjecture quant à la raison pour laquelle votre première approche n'a pas fonctionné, mais votre deuxième est que forEach ne retourne pas réellement un tableau, et si c'est le cas, appeler map dans forEach retournerait un tableau de tableaux (mais, encore une fois, ce n'est pas le cas). Je ne sais pas comment React gérerait cela, mais React sait comment gérer un seul tableau, ce que retourne votre dernière approche).

2
jaredkwright