2017-10-20 19 views
1

J'ai une petite implémentation de glisser-déposer en utilisant react-dnd. Il y a deux colonnes, en faisant glisser de la colonne de droite vers la gauche active l'élément d'état spécifique.React.js - Array.unshift() ne pas mettre à jour le tableau en front-end

Lors de la suppression, pushCard() est appelée, qui (comme son nom l'indique), pousse l'élément déplacé dans la matrice d'états activés, c'est-à-dire status_data.

Mais le problème est, status_data.push(itemToPush), pousse le nouvel élément à la fin de la matrice. Je voulais pousser l'élément sur le tableau, c'est-à-dire l'index 0 du tableau.

status_data.unshift(itemToPush) œuvres dans ce cas, mais unshift ne met à jour le tableau dans le state et le back-end, mais il ne montre pas le array mis à jour sur le front-end. Au contraire, il continuerait simplement à pousser le même élément qui a été traîné en premier.

Simple description of problem in a GIF.

pushCard:

pushCard(item) { 
    const { status_data } = this.state.template; 
    const itemToPush = { 
     title : item.title || 'CUSTOM', 
     type_id : item.type_id, 
     color : item.color || '#000', 
     type: item.type, 
     require_notes: item.require_notes || false, 
     require_estimate: item.require_estimate || false 
    }; 
    status_data.unshift(itemToPush); 
    this.setState(Object.assign(this.state.template, { status_data })); 
} 

renderActiveStatuses

renderActiveStatuses() { 
    let renderedResult = ''; 
    if (this.state.template.status_data.length < 0) { 
     renderedResult = (<p>No status active in this template.</p>); 
    } else { 
     renderedResult = this.state.template.status_data.map((status, i) => { 
     return (
      <Status deleteStatus={this.deleteStatus} handleStatusUpdate={this.onStatusUpdate} index={i} id={status.id} moveCard={this.moveCard} statusData={status} key={status.id} /> 
     ); 
     }); 
    } 
    return renderedResult; 
} 

renderActiveStatuses est appelé dans la fonction render du composant.

Répondre

1

Les status objets, comme le itemToPush que vous montrez ici, n'ont aucune propriété id, celle que vous utilisez comme key dans Status. Vous pouvez essayer key={i} à la place (même si l'utilisation de l'index de la carte n'est pas la meilleure idée).

Vous pouvez générer un (probablement) identifiant unique comme celui-ci:

const itemToPush = { 
    id: Math.random().toString(36).substr(2, 16), 
    ... 
} 

et utiliser status.id maintenant comme vous le faisiez auparavant.

Il existe de meilleurs générateurs d'ID s'il y a un risque dans le cas où vous en générez des millions.

+0

Si je fais 'key = {i}', cela dérange 'react-dnd'. Comme il a besoin d'un 'index 'unique pour chaque élément. –

+0

Le 'id' de' Status' sera également erroné. Vous pouvez essayer quelque chose comme 'status.title + status.type_id + i'. Sinon, vous aurez besoin d'une fabrique pour vos éléments d'état qui génère un ID aléatoire pour eux, c'est-à-dire une fonction qui renvoie un de ces éléments en fonction de son type, en ajoutant un ID à l'objet. – JulienD

+0

Mis à jour avec un générateur d'ID. – JulienD

1

Que pensez-vous de cela?

this.setState({template: Object.assign({}, this.state.template, { status_data })}); 

Comme vous l'avez fait dans votre question, vous n'assignez à votre état le contenu de , alors que l'original ne change jamais, de sorte que votre état devient

state = { 
    template: {status_data: ...}, 
    status_data: ..., 
    ... 
} 
+0

Vous voulez probablement 'Object.assign ({}, this.state.template, {status_data})' de sorte que vous ne modifiez pas l'état directement (https://reactjs.org/docs/state-and- lifecycle.html # do-not-modify-state-direct) –

+0

Oui, j'ai mis à jour la réponse. – JulienD

+0

@JulienD merci. Mais cela ne résout pas le problème: 9 –