2017-05-31 4 views
0

J'ai une classe très basique Person qui nécessite un paramètre appelé data.Modification des propriétés de classe avec Object.assign mais renvoi de l'instance de classe

class Person implements PersonInterface { 

    constructor(public data) { 

    } 

    get name(): string { 
     return this.data.name; 
    } 

} 

const person: PersonInterface = new Person({ name: "Aristona }); 

Dans mon magasin Redux, je conserve toutes les personnes dans un tableau. Il ressemble à ceci:

[Person, Person, Person, Person] 

L'utilisateur peut modifier la propriété d'un nom Person. Donc, mon réducteur ressemble à ceci:

case Constants.PERSON_UPDATE_SUCCESS: 
    const person = Object.assign({}, action.payload.person.data, { 
    name: action.payload.name 
    }); 

    return { 
    ...state, 
    persons: [ 
     person, 
     ...state.persons.filter(p => p.id !== person.id) 
    ] 
    }; 

Il ne fonctionne pas parce que Object.assign retourne la propriété data. Ce dont j'ai besoin est Person objet avec data propriété mise à jour. Si je pouvais muter les données, il ressemblerait à ceci:

person.name = action.payload.name; 

Sinon, mon personnes tableau ressemble à ceci:

[Person, Person, Person, Person, Object] // Object is data 

et il brise toutes les itérations.

J'ai essayé de faire ceci:

const updatedData = Object.assign({}, action.payload.person.data, { 
    name: action.payload.name 
}); 

const person: PersonInterface = new Person(updatedData); 

Alors qu'en théorie, il travaillerait, malheureusement, je ne peux pas instancier une classe comme cela sans apporter des changements majeurs sur mes PersonFactory classes.

Existe-t-il un moyen d'y parvenir sans casser l'immuabilité de Redux?

Merci.

+1

Si vous voulez vraiment utiliser des classes, je vous recommande de créer simplement une nouvelle instance de la classe en utilisant 'new'. – Sulthan

+1

Réagir et surtout redoubler une approche plus fonctionnelle plutôt qu'objective. Je ne peux pas penser à un bon moyen de faire ce que vous essayez de faire, malheureusement.Je dois demander, avez-vous vraiment besoin d'utiliser des classes pour votre état? L'état est juste une structure de données et ne bénéficierait pas vraiment d'être une instance de classe. – DonovanM

+0

Voir ma réponse sur pourquoi l'utilisation de classes pour les données dans Redux est déconseillée: https://stackoverflow.com/questions/44268317/clone-and-then-mutate-approach-in-redux/44270061#44270061. – markerikson

Répondre

0

1) Il est pas une bonne pratique pour stocker des instances de classe dans votre état

Le premier principe de trois principes de Redux dit

L'état de votre application entière est stockée dans un arbre d'objets à l'intérieur un seul magasin. Cela facilite la création d'applications universelles, car l'état de votre serveur peut être sérialisé et hydraté dans le client sans effort de codage supplémentaire ...

alors envisagez de modifier votre état pour avoir uniquement des données sérialisables.

2) C'est une bonne pratique d'utiliser des outils comme immutablejs, cela élimine tous les problèmes d'immuabilité et pour toujours.

3) C'est une bonne habitude de diviser vos fonctions de réduction, pensez à utiliser combineReducer, si vous le faites, vous aurez un réducteur responsable uniquement de la branche persons de l'état.

4) Si vous devez continuer avec la solution actuelle, je pense que vous devez instancier une personne new à chaque mise à jour.

+0

Je ne suis pas d'accord avec 1. Il est tout à fait normal d'enregistrer des instances de classes à stocker. C'est plus sur la complexité de l'objet donné que sur le fait que c'est une classe. Par exemple, nous sauvegardons tous les instances 'Date' et' Error' à stocker. – Sulthan

+0

cela fonctionne, mais il n'est pas évolutif car il n'est pas sérialisable, que se passe-t-il si vous voulez conserver votre état dans localStorage, ou si vous avez un rendu côté serveur et que vous voulez transférer l'état du serveur au client? – Faris

+1

@Sulthan: non, il n'est pas "normal" d'enregistrer des instances de classes dans le magasin - il est fortement déconseillé. Vous pouvez le faire, mais idéalement, vous ne devez mettre que des données simples dans le magasin (objets, tableaux et primitives). Des choses comme les dates et les erreurs doivent être représentées par des chaînes ou des nombres. – markerikson