I'm making a mobile app in React-Native where the user must login first to use the functionalities. If the user logs in succesfully, I save the username with AsyncStorage.setItem
, which works great.
I try to get the value on app start using AsyncStorage.getItem
, using the code:
class LoginScreen extends Component {
static PropTypes = {
dispatch: PropTypes.func,
fetching: PropTypes.bool,
attemptLogin: PropTypes.func
}
isAttempting = false
constructor (props) {
super(props)
this.state = {
username: '',
password: '',
isLoaded: {false}
}
}
componentDidMount(){
const { username, password } = this.state
this._getSavedUsername();
// AsyncStorage
// .getItem('@MobAppCorpStore:username')
// .then((v_username) => { this.setState({ username: v_username, isLoaded: true }) });
}
async _getSavedUsername() {
const { username } = this.state
try {
const value = await AsyncStorage.getItem('@MobAppCorpStore:username');
if (value !== null){
this.setState({ username: value});
}
} catch (error) {
// Error retrieving data
alert('Containers/LoginScreen - _getSavedUsername error')
console.log('Containers/LoginScreen - get username error : ', error)
}
}
...
render () {
...
<Form style={styles.form_style}>
<Item floatingLabel >
<Label>{I18n.t('Global.username')}</Label>
<Input
style={styles.input_style}
//autoFocus = {true}
returnKeyType='next'
value={username}
onChangeText={username => this.setState({username})}
autoCapitalize="none"
blurOnSubmit={false}
/>
</Item>
<Item floatingLabel last >
<Label>{I18n.t('Global.password')}</Label>
<Input
style={styles.input_style}
returnKeyType='go'
secureTextEntry={true}
value={password}
onChangeText={password => this.setState({password})}
onSubmitEditing={this._handlePressLogin}
autoCapitalize="none"/>
</Item>
</Form>
...
}
...
}
The value is correctly recovered and displayed in the TextInput (Input from NativeBase). But I also get this error:
Warning: Can't call setState (or forceUpdate) on an unmounted component.
This is a no-op, but it indicates a memory leak in your application. To fix,
cancel all subscriptions and asynchronous tasks in the componentWillUnmount
method.
If I understood correctly, AsyncStorage is an async function, so the value is recovered "later", after the lifecycle in this case?
What is the correct way to get a value using AsyncStorage at the start of an app/screen?
(I've already seen this post What is the correct way to use AsyncStorage to update state in React-Native? but I think it's not similar to my case)