1

I have a problem calling this.setState({}) in componentDidMount(). If I call this.setState({}) in comonentDidMount() it seems that it isn´t updating the state beacause if I call my function to fetch data from firestore the state is "" and not the set one in componentDidMount()

constructor:

this.state = {
  userid: '',
  username: '',
  useremail: ''
}

componentDidMount:

AsyncStorage.getItem('@userProfileDocID', function (error, result){
  if (result != null) {
    this.setState({ userid: result }, () => {
      alert(this.state.userid);
    });
  }
}.bind(this));

fire.collection('User').doc(this.state.userid).get().then(function (doc) {
  if (doc.exists) {
    this.setState({
      username: doc.name,
      useremail: doc.email
    });
  }
}.bind(this));

render:

return (
    <SafeAreaView style={{ alignItems: 'center' }}>
      <View style={{
        borderRadius: 5,
        width: 350,
        height: 350,
        shadowColor: 'black',
        shadowOffset: {width: 0, height: 0},
        shadowOpacity: 0.1,
        shadowRadius: 1.5,
        backgroundColor: 'white',
        alignItems: 'center',
        padding: 20 
      }}>
        <Icon name="ios-contact" color={'#d0d0d0'} size={100} />
        <Text>UserID: {this.state.userid}</Text> {/* <-- This Works (gets updated) */}
        <Text>Username: {this.state.username}</Text>
        <Text>Email: {this.state.useremail}</Text>
      </View>
    </SafeAreaView>
)

2 Answers2

1

AsyncStorage is an asynchronous function as the name suggests, so you have to wait for the response, that's why state has nothing because asyncstorage hasn's finished.

    try {
      const value = await AsyncStorage.getItem('@userProfileDocID');
      this.setState({ userid: value})
    } catch (error) {
      // Error retrieving data
    }

And in my honest opinion you should use ComponentDidMount it is safer but it's my opinion

see this for more opinions

calling setState in ComponentWillMount is dangerous because you take a risk in calling setState while rendering

MPN7
  • 1,112
  • 1
  • 10
  • 13
  • But why does the variable is not empty at the call at the render method? And if I now call this.state.userid in componentDidMount() after I got it from Asyncstorage it is empty. – Luis Rosengarten Mar 29 '19 at 18:00
  • you need to use `await`! from componentdidmount call an `async` function with the code from my answer and if you only want to render your component when the state is set you can had a if before the return `if(this.state.userid){return(//your views)}else{return()}` – MPN7 Mar 29 '19 at 19:59
0

Instead of put code in componentDidMount() try to put it in the constructor() or in the componentWillMount().

I recommend to put that code in the end of the constructor() method because componentWillMount will be deprecated in next versions of React Native

SmoggeR_js
  • 2,950
  • 4
  • 22
  • 52