2017-09-01 3 views
1

Ma question est la suivante. J'ai deux composants. Le premier composant est un recadrage d'image. Le deuxième composant est celui que je devrais afficher l'image recadrée. Le problème auquel je suis confronté est que je peux passer l'image recadrée à mon deuxième composant mais je dois appuyer sur le bouton qui recadre l'image et passer au deuxième composant, deux fois. Au second clic, seule mon image passe au second composant. Mais je peux afficher l'image recadrée dans le premier composant en un seul clic. Je pense que cela se produit parce que dans les réactions, les changements d'état ne se produisent pas immédiatement. Alors, comment puis-je résoudre ce problème.Appeler des fonctions après qu'un changement d'état se produise dans reactjs

Mon approche était de créer une fonction prop dans le 1er composant comme this.props.croppedImage(this.state.preview.img); ici this.state.preview.img est l'image rognée. Et dans le 2ème composant, je récupère l'image recadrée en appelant la fonction prop.

Mon code

1er composant (Cropper)

class CropperTest extends React.Component { 

    constructor(props) { 

     super(props); 

     this.state = { 
      name: "beautiful", 
      scale: 1, 
      preview: null, 
     } 

     this.handleSave = this.handleSave.bind(this); 

    } 

    handleSave =() => { 

     const img = this.editor.getImageScaledToCanvas().toDataURL(); 

     this.setState({ 
      preview: { 
       img, 
       scale: this.state.scale, 
      } 
     }) 

     this.props.croppedImage(this.state.preview.img); 

    } 

    setEditorRef = (editor) => { 
     this.editor = editor 
    } 

    render() { 
     return (
      <div> 
       <div className="overlay"></div> 

       <div className="crop_div"> 
        <AvatarEditor 
         image={this.props.cropImage} 
         ref={this.setEditorRef} 
         width={450} 
         height={450} 
         border={50} 
         color={[255, 255, 255, 0.6]} // RGBA 
         scale={this.state.scale} 
         rotate={0} 
        /> 
       </div> 



       <div className="zoom_slider text_align_center"> 
        <input className="crop_btn" type='button' onClick={this.handleSave} value='Save'/> 

       </div> 

      </div> 
     ) 
    } 
} 

export default CropperTest; 

2ème composante

Ici, je fais essentiellement ce qui suit.

<CropperTest croppedImage = {this.getCroppedImg}/> 

    getCroppedImg(img){ 

      alert("Perfect Storm"); 
      this.setState({ 

       previewImg:img 

      }) 

     } 
+0

setState accepte un deuxième paramètre comme fonction de rappel lorsque l'état a été mis à jour. Essaye le! – Brian

+0

Aussi, pas besoin de pré-lier vos méthodes de classe si vous les déclarez comme 'method =() => {}' – ffxsam

+0

@ffxsam merci mais ce n'est pas la racine de mon problème – CraZyDroiD

Répondre

3

Je pense que cela se produit parce que dans les changements d'état reactjs ne se produisent pas immédiatement. Alors, comment puis-je résoudre ce problème?

De l'React#setState,

setState (mise à jour, [rappel])

setState() enqueues passe à l'état des composants. Le setState ne met pas immédiatement à jour l'état. setState() ne met pas toujours immédiatement à jour le composant. Il peut lot ou différer la mise à jour jusqu'à plus tard. Cela rend la lecture this.state droit après avoir appelé setState() un pitfall.Instead potentiel, utilisez componentDidUpdate ou un rappel setState(setState(updater, callback))

Appelez le this.props.croppedImage dans le setState callback.You va obtenir des valeurs mises à jour de l'état du composant. Dans votre cas,

this.setState({ 
    preview: { 
    img, 
    scale: this.state.scale, 
    } 
},() => { 
    this.props.croppedImage(this.state.preview.img); 
})