2
votes

Basculer l'état de réaction

Considérez ceci comme mon état de réaction

someEvent = (event) => {
if (event === "a") this.setState({a: true, b: false, c: false, d: false, e: false})
if (event === "b")this.setState({a: false, b: true, c: false, d: false, e: false})
....
....
....
}

Maintenant, je veux basculer l'état sur le clic du bouton et si l'événement est égal à la clé (a, b, c, d, e ) dans mon état, je veux que ce soit vrai et reste faux. Actuellement, ce que je fais est ..

state = {
a: true,
b: false,
c: false,
d: false,
e: false 
}

Au lieu d'écrire / définir chaque état sur false, je veux que l'événement donné égal à la clé ait une valeur vraie dans mon état et tout le reste est faux,

Comment puis-je le faire?


0 commentaires

7 Réponses :


4
votes

Vous pouvez le faire en suivant le code:

this.setState({
  a: event === "a",
  b: event === "b",
  c: event === "c",
  d: event === "d",
  e: event === "e"
});


2 commentaires

@downvoters: Voulez-vous expliquer la raison du vote négatif? Je n'arrive pas à voir le problème avec cette réponse


Je n'ai pas voté contre, mais cela nécessite d'écrire chaque propriété d'état. Pour un grand nombre de propriétés, cela peut être fastidieux et sujet aux erreurs. Mais c'est une excellente solution s'il n'y a pas beaucoup de propriétés.



1
votes

Vous pouvez initialiser un objet avec tous les états comme faux

this.setState(obj);

ou en fonction des clés de cet objet.state

obj[event] = true;

suivant définissez l'état sur true pour toute condition valide

for (let key in this.state) obj[key] = false;

définissez maintenant l'état

const obj = {};
for (let char = 'a'; char <= 'e'; char++) obj[char] = false;

PS: vous devez gérer les erreurs et les événements qui pourraient casser le code ici car je n'ai pas ajouté de validation.

PS (2): Cela vous permet de gagner du temps, au lieu d'écrire chaque instruction if / else ou switch vous-même.


0 commentaires

3
votes

Vous pouvez faire quelque chose comme ceci

Object.keys( this.state )
        .map( Key => {
            if(event === this.state[Key]){
              this.setState({this.state[Key] : true});
            }else{
              this.setState({this.state[Key] : false});
            }
     } );
 })


2 commentaires

Ne pensez-vous pas que le fait d'appeler this.setState pour aucune des clés dans l'état aura des problèmes de performances?


J'ai légèrement amélioré ma réponse, veuillez vérifier.



1
votes

Eh bien, vous pouvez simplement faire comme ça.

someEvent = (event) => {
    this.setState({ [event]: true })
}

donc si event === "a" alors il ne définiraState que pour un idem pour b, c, d, e cette condition unique définira tous les états pour vous.


0 commentaires

4
votes

Ici avec une seule ligne.

Utilisez Object.keys () pour obtenir le tableau de clés de l'objet, puis parcourez le tableau pour vérifier si l'événement est égal à l'état. S'il est trouvé, l'état est vrai sinon faux;

let event = 'c'
let state = { a: true, b: false, c: false, d: false, e: false }
Object.keys(state).forEach(s => state[s] = s === event)
console.log(state)


3 commentaires

Ne pensez-vous pas que le fait d'appeler this.setState pour aucune des clés dans l'état aura des problèmes de performances?


Je ne comprends pas très bien. Je n'ai pas d'expérience en reactjs, donc désolé pour cela mais je pense que cette réponse est plus ou moins utile. L'appel de this.setState à la fin de ce code fonctionnera à mon avis. Si vous êtes vraiment préoccupé par les performances, je peux optimiser cela un peu plus pour vous.


J'apprécie tellement votre réponse. setState restitue notre DOM (comme il le compare avec le DOM virtuel et restitue les modifications). J'ai cependant voté pour votre réponse :)



1
votes

il semble que vous modélisez votre état de manière inefficace - s'il y aura toujours une valeur vraie et que tout le reste est faux, vous pouvez simplement faire:

someEvent = (event) => {
  this.setState((previousState) => {
    Object.keys(previousState).forEach((v) => { previousState[v] = false })
    previousState[event] = true
    return previousState;
  })
}

si vous êtes sur votre modèle d'état actuel, cela devrait fonctionner. voici un violon

state = {
  currentlyTrue: a
}
someEvent = (event) => {
  this.setState({currentlyTrue: event})
}


2 commentaires

Ne pensez-vous pas que le fait d'appeler this.setState pour aucune des clés dans l'état aura des problèmes de performances?


Je n'appelle setState qu'une seule fois - je mute simplement l'objet previousState pour obtenir le résultat final souhaité avant de le renvoyer.



2
votes

Une autre façon de procéder

let updateObject = [...this.state];
Object.keys( this.state )
        .map( Key => {
            if(event === this.state[Key]){
              updateObject[key] = true;
            }else{
              updateObject[key] = false;
            }
     } );
 });

this.setState({...this.state,updateObject});


0 commentaires