Dans ce composant de réaction, je souhaite afficher les données à l'écran lorsque l'utilisateur clique sur le bouton «Soumettre», mais il faut appuyer deux fois sur le bouton pour que les données s'affichent.
Voici mon code snippet:
class Invoice extends Component { constructor(props) { super(props); this.state = { items: [], isLoaded: false, transId: "" ,flag:true,errorFlag:false,show:false,displayContent:"",invoice:"",invoiceXmlBody:"",invoiceResult:"",invoiceTransId:"",invoiceResultFlag:false,invoicedisplayFlag:false}; } handleChangeInvoice(e) { console.log("inside handleChangeInvoice"); let invoiceXml = e.target.value; if (invoiceXml !== undefined) { this.setState({ invoiceXmlBody: e.target.value }); } } handleSubmitInvoiceXml =e=>{ console.log("*******************inside handleSubmitInvoiceXml***************"); let url = "http://localhost:8080/postInvoiceXml"; fetch(url, { method: "POST", body: JSON.stringify(this.state.invoiceXmlBody), }) .then(res => res.json()).then(data=> { this.setState({items:data}); console.log(this.state.items[0].status); console.log("response========="+JSON.stringify(data)); if(data===undefined){ this.state.invoiceResultFlag=true; } else{ this.state.invoicedisplayFlag=true; } } ) } render() { console.log("---------------------------"+this.state.invoicedisplayFlag); return ( <div className="App"> <br/> <label className="lable" style={{marginRight:19}}> InvoiceXml: <input type="text" name="invoiceXml" placeholder="Enter invoice xml" onBlur={this.handleChangeInvoice.bind(this)} style={{marginLeft:15}} /> </label><br/><br/> <input type="button" onClick={this.handleSubmitInvoiceXml} name="Submit" value="Submit" className="submitButton" /> <br/> <br/><br/> <div className={this.state.invoicedisplayFlag?"showDisplay":"hide"}> {this.state.items.map((item,i) => ( <div> <h2>Invoice No is: {item.invoiceNo}</h2> <h2>Transaction id is: {item.transId}</h2> <h2>Status: { item.status ? 'Success' : 'Failed' }</h2> </div> ))} </div> </div> ); } }
comment puis-je résoudre ce problème?
3 Réponses :
il est facile de trouver pourquoi, en gros vous définissez directement une valeur dans votre état, vous devez le faire en utilisant setState ()
comme le dit la documentation
donc votre code est:
this.setState({ items:data, invoiceResultFlag: !data, invoicedisplayFlag: !!data, });
mais il devrait be:
this.setState({items:data}, ()=>{ if(data===undefined){ this.setState({invoiceResultFlag: true}) } else { this.setState({invoicedisplayFlag: true}); } });
Une autre chose que j'ai remarquée est que vous voulez définir un état après avoir défini un état, vous pouvez alors utiliser le rappel de setState ()
if(data===undefined){ this.setState({invoiceResultFlag: true}) } else { this.setState({invoicedisplayFlag: true}); }
et enfin, je n'aime pas personnellement ces 2 setState, ce serait plus facile de tout faire en un seul endroit:
if(data===undefined){ this.state.invoiceResultFlag=true; } else { this.state.invoicedisplayFlag=true; }
Dans la fonction onClick pour ce bouton, enregistrez simplement un drapeau dans l'état du composant [Ou local à votre classe] indiquant si le bouton a été cliqué et si c'est le cas, exécutez la logique de rendu ET réinitialisez le drapeau à nouveau
J'ai rencontré un problème similaire où j'utilisais onBlur pour mettre à jour l'état d'une valeur d'entrée.
J'ai trouvé que l'on avait changé onClick en onMouseDown pour fonctionner
<input className="input-form" onBlur={(e)=>{this.setState({field1:e.target.value})}/> <button className="submit-button" onMouseDown={()=>{this.submitForm()}}>Submit</button>
Vous ne devez pas modifier l'état directement (comme
this.state.invoiceResultFlag = ..
). Utilisez plutôtthis.setState
.Avec "onDoubleClick", le composant n'est pas du tout rendu
@hindmost ... cela m'a aidé à résoudre le problème ... Pouvez-vous m'expliquer brièvement la raison derrière cela?
Attendez. Êtes-vous en train de dire que vous souhaitez afficher les données lorsque vous cliquez deux fois sur le bouton, ou que les données ne s'affichent que lorsque vous cliquez deux fois sur le bouton, mais ce n'est pas ce que vous voulez. Votre question n'est pas claire.
Mon problème était que les données lyk ne s'affichent que lorsque je clique deux fois sur le bouton, mais après avoir utilisé this.setState au lieu de modifier l'état directement, il a été résolu
Pouvez-vous m'expliquer brièvement la raison derrière cela? C'est un effet secondaire de la mutation directe de l'état.