facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.9k stars 24.3k forks source link

AsyncStorage.getItem() doesn't seem to work #18372

Closed mrded closed 5 years ago

mrded commented 6 years ago

When I try to set a value via AsyncStorage.getItem(), I cannot request it back.

Environment

Environment: OS: macOS High Sierra 10.13.3 Node: 9.8.0 Yarn: 1.5.1 npm: 5.6.0 Watchman: 4.9.0 Xcode: Xcode 9.2 Build version 9C40b Android Studio: Not Found

Packages: (wanted => installed) react: ^16.3.0-alpha.1 => 16.3.0-alpha.1 react-native: 0.54.0 => 0.54.0

Expected Behavior

await AsyncStorage.setItem('foo', 'bar');
await AsyncStorage.getItem('foo').then(console.log); // 'bar'
await AsyncStorage.getAllKeys().then(console.log); // ['foo']

Actual Behavior

await AsyncStorage.setItem('foo', 'bar');
await AsyncStorage.getItem('foo').then(console.log); // null
await AsyncStorage.getAllKeys().then(console.log); // []

Steps to Reproduce

import { AsyncStorage } from 'react-native';

it('should be able to request a value after it was set', async () => {
  await AsyncStorage.setItem('foo', 'bar');
  const output = await AsyncStorage.getItem('foo');

  expect(output).toBe('bar');
});

it('should be able to see a new key after a value was set', async () => {
  await AsyncStorage.setItem('foo', 'bar');
  const output = await AsyncStorage.getAllKeys();

  expect(output).toContain('foo');
});
omurilo commented 5 years ago

Have you remembered to put the item in asyncstorage as string (JSON.stringify) and when reading the parse item (JSON.parse) ?? this may be the mistake of many.

jeffelector commented 5 years ago

Problem is not getItem, the problem is setItem or that I think. The difference between getItem and setItem is that set not return something (except a null). So, the await of setItem never pass to the next set. Actually, even never set the data.

So, the solution (at least for me) is: not to use await insetItem.

great !!! you save my day

jorodriguez commented 5 years ago

//Login.js .. onClickListener = (viewId) => { AsyncStorage.setItem('logeado', JSON.stringify(this.usuario.auth)); AsyncStorage.setItem('usuario', JSON.stringify(this.usuario)); that.props.navigation.navigate('Principal', { }); }

..

//Welcome.js

... constructor(props) { super(props);

this.state = {
  loading: false,
   usuarioSesion : null
}
this._bootstrapAsync();

}

_bootstrapAsync = async () => {
const usuario = await AsyncStorage.getItem('usuario'); Alert.alert("json",JSON.parse(usuario)); this.setState({usuarioSesion :usuario}); };

salir = () => { AsyncStorage.removeItem('logeado'); AsyncStorage.removeItem('usuario'); this.props.navigation.navigate('AuthLoading', {}); }

its works for me.

paddy57 commented 5 years ago

I don't know what will be solution in your case but this one worked for me

Firstely i was importing some componets from react-native like this import { Text, StyleSheet, TouchableHighlight, TextInput, } from 'react-native'; import { AsyncStorage } from 'react-native';

and the AsyncStorage.getItem or AsyncStorage.setItem was not working, whatever code was there after AsunStorage was not running, so

I Modified my import like to this import { Text, StyleSheet, TouchableHighlight, TextInput, AsyncStorage } from 'react-native';

and now everything was working fine. I don't know how it got resolved, but my AsyncStorage.setItem and AsyncStorage.getItem both was working fine

AsyncStorage.setItem('DEMO', 'false');

try { let data = await AsyncStorage.getItem("DEMO"); alert(data); } catch (error) {

    }
kamirt commented 5 years ago

Hi everyone,

Problem is not getItem, the problem is setItem or that I think. The difference between getItem and setItem is that set not return something (except a null). So, the await of setItem never pass to the next set. Actually, even never set the data.

So, the solution (at least for me) is: not to use await insetItem.

Not just this I think. I've used your solution, but getItem('key', callback) and getItem('key').then() also doesn't work. Also it does'nt work directly inside componentDidMount hook. It become working when I've took this away to another function like this: _getItem = async function () { const result = await AsyncStorage.getItem('key') return result }

componentDidMount () { this._getItem().then((result) => { ..so something with result.. }) }`

dmcfadden1 commented 5 years ago

AsyncStorage.getItem(key) .then((value) => { return value; })

b3hz4d commented 5 years ago

I found solution for this Use this link https://github.com/react-native-community/async-storage/blob/LEGACY/docs/advanced/DedicatedExecutor.md

irishabhyadav90 commented 4 years ago

Even the custom Hooks (UseStorage) in React Native causing the same Problem.

import {useState, useEffect} from 'react'; import {AsyncStorage} from '@react-native-community/async-storage';

/ Hook for AsyncStorage /

const useStorage = (key, defaultValue) => { const [storage, updateStorageValue] = useState(defaultValue, ''); async function getStorageValue() { let value = key || defaultValue;

try {
  value = JSON.parse(await AsyncStorage.getItem(key)) || defaultValue;
} catch (e) {
} finally {
  updateStorageValue(value);
}

}

async function updateStorage(newValue) { try { if (newValue === null) { await AsyncStorage.removeItem(key); } else { const value = JSON.stringify(newValue); await AsyncStorage.setItem(key, value); } } catch (e) { } finally { updateStorageValue(newValue); } }

useEffect(() => { getStorageValue(); }, [getStorageValue]);

return [storage, updateStorage]; };

export default useStorage;