最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - I need to click twice on ,the button to display the component - Stack Overflow

programmeradmin1浏览0评论

In this react ponent, I want to render the data to the screen when the 'Submit' button is clicked by the user, but the button has to be pressed twice for the data to display.

Below is my 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>
    );
  }
}

how can I resolve this?

In this react ponent, I want to render the data to the screen when the 'Submit' button is clicked by the user, but the button has to be pressed twice for the data to display.

Below is my 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>
    );
  }
}

how can I resolve this?

Share Improve this question edited Jan 10, 2019 at 20:13 James Z 12.3k10 gold badges27 silver badges47 bronze badges asked Jan 10, 2019 at 17:17 kinnukinnu 3882 gold badges12 silver badges25 bronze badges 6
  • You should not modify state directly (such as this.state.invoiceResultFlag=..). Use this.setState instead. – hindmost Commented Jan 10, 2019 at 17:28
  • With " onDoubleClick" the ponent is not getting rendered at all – kinnu Commented Jan 10, 2019 at 17:30
  • @hindmost...it hepled me to resolve the issue...Can u please briefly explain me the reason behind this? – kinnu Commented Jan 10, 2019 at 17:34
  • Wait. Are you saying that you want to show the data when you click on the button twice, or that the data is only showing when you click on the button twice but that's not what you want. Your question isn't clear. – Andy Commented Jan 10, 2019 at 17:35
  • My issue was lyk data is only showing when I click on the button twice,but after I use this.setState instead of modifying state directly,it got resolved – kinnu Commented Jan 10, 2019 at 17:38
 |  Show 1 more ment

3 Answers 3

Reset to default 2

it is easy to find why, basically you are setting a value in your state directly, you should do it using setState() like the documentation says

so your code is:

if(data===undefined){
    this.state.invoiceResultFlag=true;
}
else {
    this.state.invoicedisplayFlag=true;
}

but it should be:

if(data===undefined){
    this.setState({invoiceResultFlag: true})
}
else {
    this.setState({invoicedisplayFlag: true});
}

another thing that I noticed is that you want to set an state after you set an state, then you can use the callback from setState()

this.setState({items:data}, ()=>{
    if(data===undefined){
        this.setState({invoiceResultFlag: true})
    }
    else {
        this.setState({invoicedisplayFlag: true});
    }
});

and finally, I dont personally like those 2 setState, it would be easier to do it everything in one place:

this.setState({
    items:data,
    invoiceResultFlag: !data,
    invoicedisplayFlag: !!data,
});

I ran into a similar problem where I was using onBlur to update the state of an input value.

I found changing onClick to onMouseDown to work

<input className="input-form" onBlur={(e)=>{this.setState({field1:e.target.value})}/>

<button className="submit-button" onMouseDown={()=>{this.submitForm()}}>Submit</button>

In the onClick function for that button just save a flag in the ponent state [Or local to your class] indicating if the button was clicked and if so execute the render logic AND reset the flag again

发布评论

评论列表(0)

  1. 暂无评论