58 votes

permettre tapuscrit compilateur pour appeler setState sur un seul réagir la propriété de l'etat

Je suis l'aide de la Machine à Réagir pour un projet. La composante Principale est passée de l'état avec cette interface.

interface MainState {
  todos: Todo[];
  hungry: Boolean;
  editorState: EditorState;  //this is from Facebook's draft js
}

Toutefois, le code ci-dessous (seulement un extrait) ne compile pas.

class Main extends React.Component<MainProps, MainState> {
  constructor(props) {
    super(props);
    this.state = { todos: [], hungry: true, editorState: EditorState.createEmpty() };
  }
  onChange(editorState: EditorState) {
    this.setState({
      editorState: editorState
    });
  }
}

Le compilateur se plaint de ce que, dans l' onChange méthode où je ne suis que d'essayer de setState pour l'un des biens, la propriété, todos et la propriété hungry est manquant dans le type { editorState: EditorState;}. En d'autres termes, j'ai besoin de définir l'état de tous les trois propriétés en onChange fonction pour rendre le code compilé. Pour compiler, j'ai besoin de le faire

onChange(editorState: EditorState){
  this.setState({
    todos: [],
    hungry: false,
    editorState: editorState
  });
}

mais il n'y a aucune raison de définir l' todos et de la hungry de la propriété à ce point dans le code. Quelle est la bonne façon de faire des appels setState sur une seule propriété en caractères d'imprimerie/réagir?

60voto

Nitzan Tomer Points 11798

Modifier

Les définitions pour réagir ont été mises à jour et la signature d' setState sont maintenant:

setState<K extends keyof S>(state: Pick<S, K>, callback?: () => any): void;

Pick<S, K> est un type qui a été ajouté à la Machine 2.1:

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}

Voir Mappé Types pour plus d'info.
Si vous avez toujours cette erreur, alors vous pourriez vouloir envisager de mettre à jour vos réagir définitions.

Réponse originale à cette question:

Je suis confronté à la même chose.

Les deux façons que j'ai réussi à obtenir autour de cette fâcheuse question sont:

(1) de moulage/assertion:

this.setState({
    editorState: editorState
} as MainState);

(2) le fait de déclarer l'interface des champs facultatifs:

interface MainState {
    todos?: Todo[];
    hungry?: Boolean;
    editorState?: EditorState;
}

Si quelqu'un a une meilleure solution, je serais heureux de le savoir!


Modifier

Bien que ce soit encore un problème, il y a deux discussions sur de nouvelles fonctionnalités qui permettront de résoudre ce problème:
Types partiels (Optionalized Propriétés pour les Types Existants)
et
Plus d'une frappe précise de l'Objet.attribuer et de Réagir composant setState()

23voto

Alexey Petrushin Points 1153

Mise à jour de l'état explicitement, exemple avec le compteur

this.setState((current) => ({ ...current, counter: current.counter + 1 }))

9voto

niba Points 1472

Je pense que la meilleure façon de le faire est d'utiliser Partial

Déclarer votre composant de la façon suivante

class Main extends React.Component<MainProps, Partial<MainState>> {
}

Partielle change automatiquement toutes les clés pour facultatif.

1voto

mlorber Points 21

Edit: NE PAS UTILISER cette solution, préfèrent https://stackoverflow.com/a/41828633/1420794 Voir les commentaires pour plus de détails.

Maintenant que la propagation de l'opérateur a été expédiée en TS, ma solution préférée est

this.setState({...this.state, editorState}); // do not use !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X