user992731
user992731

Reputation: 3520

Show component only once in React or React Native using localstorage

I am have the following situation where I am trying to show a screen component just once and only once using localstorge. This one is driving me mental.

App.js

...

constructor(props) {
    super(props);
    this.state = {
      isLoading: false,
    };
  }

  componentDidMount() {
    if (AsyncStorage.getItem('key')) {
      AsyncStorage.getItem('key', (value) => {
        this.setState({isLoading: value})
        Alert.alert(JSON.stringify(value))
      });
      AsyncStorage.setItem('key', JSON.stringify(true))
    }
  }

  render() {
    if (!this.state.isLoading) {
      return <Search />
    }
    return <Root />
    }

... 

Upvotes: 2

Views: 4291

Answers (3)

SyntaxNavigator
SyntaxNavigator

Reputation: 523

AsyncStorage.getItem('isShown').then((value) => {
      if(value == null){
        // Whatever you want to do just once.
        AsyncStorage.setItem('isShown', 'sth');
      }
    });

Upvotes: 0

Yury Tarabanko
Yury Tarabanko

Reputation: 45106

You need to slightly modify componentDidMount implementation and add another flag to component's state

constructor() {
   ...
   this.state = {
      isLoaded: false,
      wasShown: false
   }
}

componentDidMount() {
   AsyncStorage.getItem('key') // get key
     .then(wasShown => {
         if(wasShown === null) { // first time 
           // we need to save key for the next time
           AsyncStorage.setItem('key', '"true"')
         }

         this.setState({isLoaded: true, wasShown})
      })
  }

render() {
  const { isLoaded, wasShown } = this.state

  // you can't tell if this component was shown or not render nothing
  if(!isLoaded) { return null }

  if(!wasShown) {
    return <Search />
  } 

  return <Root/>
}

BTW if you include async/await support to your babel presets you could make this code way simpler

async componentDidMount() {
   const wasShown = await AsyncStorage.getItem('key') // get key

   if(wasShown === null) {
     await AsyncStorage.setItem('key', '"true"')
   }

   this.setState({isLoaded: true, wasShown}
  }

Upvotes: 1

Yozi
Yozi

Reputation: 12755

Show something else while you check storage for value. After you have got the value just set state and show your screen. In other words, you should open your screen component only after you know for sure that you have not shown the screen yet.

Upvotes: 0

Related Questions