Rajendran Nadar
Rajendran Nadar

Reputation: 5438

Do async call before rendering data in react native

My Asyc call is running after the data is rendered I tried running my Asyc call inside constructor and even inside componentDidMount but nothing worked.

My db structure..

Firebase Real time database

My query in jsx file

for(var i = 1; i <= 6; i++) {
    Firebase.database().ref('/' + i).on('value', function(snapshot) {
        value[i] = snapshot.val().state;
    });
}
console.log(value);

The issue is I want to load images according to the data in the database inside my react native app.

<View style={styles.container}>
  <View style={styles.parent}>
    // This is only one child
    <TouchableOpacity style={styles.child} id='1' onPress={(event) => this.getState(event, '1')} activeOpacity={1}>
      <Image style={styles.img} source={value[1]} /> // This line is not outputting any image because the array is empty
      <Text style={styles.title}>LED 1</Text>
    </TouchableOpacity>
    // I have 6 child and want to keep the states separate for all
</View>

GetState function

getState (event, BtnId) {
    value[BtnId] = this.state.mode_1 ? require('./img/on.png') : require('./img/off.png')
    Firebase.database().ref(BtnId).update({
        'state': value[BtnId]
    });     
}

If you want more details plz let me know.

Upvotes: 1

Views: 2151

Answers (2)

Rajendran Nadar
Rajendran Nadar

Reputation: 5438

It is not advised to do an async call before rendering, So the proper approach is to start the async call in componentDidMount and use a flag from the local state to run a spinner or a loading indicator until the async call resolves or rejects.

For React hooks do the async call in React.useEffect and in a similar way toggle the value of the local state hook to render the spinner or the data conditionally.

Upvotes: 0

William
William

Reputation: 942

You can simplify resolve this by setState.

async componentDidMount () {
const imageUrl = await yourAsyncProcess()
this.setState({imageUrl: imageUrl})
}

And render it with your updated state

<View style={styles.container}>
  <View style={styles.parent}>
    <TouchableOpacity style={styles.child} id='1' onPress={(event) => this.getState(event, '1')} activeOpacity={1}>
      <Image style={styles.img} source={uri: {this.state.imageUrl}} /> // This line is not outputting any image because the array is empty
      <Text style={styles.title}>LED 1</Text>
    </TouchableOpacity>
</View>

Upvotes: 1

Related Questions