2
votes

Pourquoi l'État ne disparaît-il que lors de l'attribution de variables?

J'ai une configuration très simple pour une galerie de fichiers que je crée, qui implique un composant maître et deux sous-composants. L'aperçu de l'image comporte bien sûr des flèches gauche et droite, qui sont transmises et renvoyées, une fonction appelée de manière créative "clickHandler" qui met simplement à jour l'état du fichier en cours d'examen.

Cependant, lors de l'appel de l'événement clickHandler, et en créant une variable temporaire à modifier et renvoyer à l'état, l'application plante sur un _this.state.activeFile n'est pas une erreur de fonction .

La partie étrange de ceci, cependant , est que l'état est complètement lisible. Il peut console.log () parfaitement sortir, et ce n’est qu’en essayant de l’attribuer à une variable à modifier que cela fait une erreur.

Voici le sous-composant qui passe très bien:

state={
    activeFile: 2
}
clickHandler=(direction)=>{
    console.log (this.state); // > Object { activeFile: 2 }
    console.log (this.state.activeFile); // > 2
    let temp =  (this.state.activeFile) // 🛑 TypeError: _this.state.activeFile is not a function

    // vvv Likely unrelated, but posted also for context
    // evals left or right to plus or minus
    (direction==="prev"?temp-=1:(direction==="next"?temp+=1:""))
    this.setState({activeFile: temp})
}

Plus de détails: https://i.imgur.com/BGNqtp7.png

Et voici où la méthode est appelée.

<FileView 
    file={this.props.media[this.state.activeFile]} 
    handler={this.clickHandler} 
    active={this.state.activeFile} 
    max={this.props.media.length}
/>

Plus de détails: https://i.imgur.com/okvE7T3.png

Comme vous pouvez le voir, les données sont présentes et lisibles, mais non assignables. Je n'ai jamais rien vu de tel et j'ai essayé une myriade de solutions comme this.state ["activeFile"] en vain.

Celle-ci me lance vraiment pour boucle, j'apprécie toute aide à l'avance!

Prototype Codepen non professionnel pour la démonstration:

https://codepen.io/Jop/pen/vvJrqv


3 commentaires

Vous devriez publier du code et des messages d'erreur en utilisant les outils de formatage disponibles au lieu de publier des images, cela aide beaucoup :)


vous avez plus de code dans clickHandler () que vous avez commenté comme eval left ou. droit à plus ou moins , vous devriez le publier aussi


Je n'étais pas prêt pour un dabbing Luigi


4 Réponses :


0
votes

Vous pouvez consulter ceci.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

<FileView handler={this.clickHandler.bind(this)} />


2 commentaires

N'est-ce pas redondant car la fonction de flèche ES6 s'en charge déjà? Il est également déjà dans la bonne portée, car console.log () atteint le même état.


stackblitz.com/edit/react-vlvudm J'ai essayé ce que vous vouliez faire ici. mais pas de problèmes



0
votes

Lorsque vous souhaitez modifier votre état en fonction de la valeur précédente, il n'est pas recommandé d'utiliser this.state. [x] directement dans la fonction setState , comme il est sujet aux bogues.

La méthode recommandée est d'utiliser this.setState (prevState => ({})) et d'utiliser les variables de previousState .

De plus, l'envoi de -1 et 1 à partir de vos fonctions facilite considérablement le traitement:

MediaViewer: p >

<div className="info-view_paging">
    {props.active < 1 ? <div></div> : <div className="info_pager" onClick={props.handler(-1)}><button>previous</button></div>}
    <div></div>
    {props.max > props.active ? <div className="info_pager" onClick={props.handler(1)}><button>next</button></div> : <div></div>}
</div>

ActiveFile:

clickHandler = offset => event => {
    this.setState(prevState => ({ activeFile: prevState.activeFile + offset }))
}


1 commentaires

Merci! Cela l'a résolu! Je suppose que cela a dû être un problème avec l'état asynchrone ou quelque chose du genre, compte tenu de la façon dont l'état précédent l'a résolu. En ce qui concerne "next" et "prev", je travaille avec un développeur plus junior, donc de petites choses qui gardent des bits sémantiques comme ça sont un peu plus faciles pour eux à analyser quand je les leur confie, même à l'intérieur des ternaires .



2
votes

Ce n'est pas quelque chose avec react, c'est quelque chose avec javascript! Le code avec l'erreur, vous avez posté comme ceci:

let temp =  this.state.activeFile;

if (direction === "prev") {
  temp -= 1;
} else if (direction === "next") {
  temp += 1;
}

Mais à cause de la façon dont la syntaxe fonctionne, javascript voit cela comme

let temp = (this.state.activeFile)(direction==="prev"?temp-=1:(direction==="next"?temp+=1:""))

Et vous voyez comment il pense qu'il attend une fonction maintenant;) Si vous le réécrivez dans

let temp =  (this.state.activeFile) // 🛑 TypeError: _this.state.activeFile is not a function

// vvv Likely unrelated, but posted also for context
// evals left or right to plus or minus
(direction==="prev"?temp-=1:(direction==="next"?temp+=1:""))

Cela devrait fonctionner :)


1 commentaires

Oh! Cela a beaucoup plus de sens! Je suppose que c'est l'un de ces rares cas où l'interpréteur n'est pas capable de se formater automatiquement à cause du ternaire. Merci, cela clarifie vraiment les choses - et je serai beaucoup plus prudent lorsque je les utiliserai à l'avenir!



0
votes

Vous obtenez une erreur car le code est interprété comme

clickHandler=(supdawg)=>{
    let temp = (this.state.activeFile)
    if (supdawg === "left") { temp -=1}
    else if (supdawg === "right") { temp+=1}
    else {temp = ""}
    this.setState({activeFile: temp})
}

Ajoutez donc un point-virgule avant la fonction ternaire ou utilisez else if Les deux devraient fonctionner

 clickHandler=(supdawg)=>{
    let temp = (this.state.activeFile);
    (supdawg==="left" ? temp-=1 : (supdawg==="right") ? temp+= 1 : "");
    this.setState({activeFile: temp});
}

ou

let temp = (this.state.activeFile)(direction==="prev"?temp-=1:(direction==="next"?temp+=1:""))


0 commentaires