Reputation: 3520
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
Reputation: 523
AsyncStorage.getItem('isShown').then((value) => {
if(value == null){
// Whatever you want to do just once.
AsyncStorage.setItem('isShown', 'sth');
}
});
Upvotes: 0
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
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