react native - this.setState inside Promise cause strange behavior -


simplified issue. calling this.setstate inside promise, renders before ends pending promise.

my problems are:

  1. the this.setstate not immediatly returned
    • i expected async, pending promise closed first.
  2. if break inside render function, catch inside promise called.
    • maybe same issue 1) seems render still in context of promise in this.setstate called.

import dummydata_rankrequests "../dummydata/rankrequests"; class rankrequestlist extends component {    constructor(props) {     super(props);       this.state = { loading: false, data: [], error: null };      this.makerankrequestcall = this.makerankrequestcall.bind(this);     this.renderitem = this.renderitem.bind(this);   }    componentdidmount() {      // works expected     // console.log('start set');     // this.setstate({ data: dummydata_rankrequests.data, loading: false });     // console.log('end set');      this.makerankrequestcall()     .then(done => {       // never here       console.log("done");     });       }    makerankrequestcall() {     console.log('call makerankrequestcall');     try {       return new promise((resolve, reject) => {         resolve(dummydata_rankrequests);       })       .then(rankrequests => {         console.log('start makerankrequestcall-rankrequests', rankrequests);         this.setstate({ data: rankrequests.data, loading: false });         console.log('end _makerankrequestcall-rankrequests');         return null;       })       .catch(error => {         console.log('_makerankrequestcall-promisecatch', error);         this.setstate({ error: rrerror.getrrerror(error), loading: false });       });     } catch (error) {       console.log('_makerankrequestcall-catch', error);       this.setstate({ error: rrerror.getrrerror(error), loading: false });     }   }    renderitem(data) {     const height = 200;     // force unknown named module error here     return (       <view style={[styles.item, {height: height}]}>       </view>     );   }    render() {     let data = [];     if (this.state.data && this.state.data.length > 0) {       data = this.state.data.map(rr => {         return object.assign({}, rr);       });     }     console.log('render-data', data);     return (       <view style={styles.container}>         <flatlist style={styles.listcontainer1}           data={data}           renderitem={this.renderitem}         />       </view>     );   } } 

currrent logs shows:

  • render-data, []
  • start makerankrequestcall-rankrequests
  • render-data, [...]
  • _makerankrequestcall-promisecatch error: unknown named module...
  • render-data, [...]
  • possible unhandled promise

android emulator "react": "16.0.0-alpha.12", "react-native": "0.46.4",

edit: wrapping settimeout around this.setstate works

    settimeout(() => {       this.setstate({ data: respdata.data, loading: false });     }, 1000); 

edit2: created bug report in react-native github in parallel https://github.com/facebook/react-native/issues/15214

both promise , this.setstate() asynchronous in javascript. say, if have following code:

console.log(a); networkrequest().then(result => console.log(result)); // networkrequest() promise console.log(b); 

the , b printed first followed result of network request.

similarly, this.setstate() asynchronous so, if want execute after this.setstate() completed, need as:

this.setstate({data: rankrequests.data}, () => {   // code needs run after changing state }) 

react re-renders every time this.setstate() gets executed, hence getting component updated before whole promise gets resolved. problem can solved making componentdidmount() async function , using await resolve promise:

async componentdidmount() {   let rankrequests;   try {     rankrequests = await this.makerankrequestcall() // result contains data   } catch(error) {     console.error(error);   }   this.setstate({ data: rankrequests.data, loading: false }, () => {     // need run after setting state   }); } 

hope helps.


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -