Reputation: 11
I researched the problem in AsyncStorage.getItem. Many of comment said we should apply await and anync on AsyncStorage, such as
React Native AsyncStorage returns promise instead of value.
AsyncStorage.getItem returning promise
However, it still return Promise to me like the snapshot below. Inside this Promise, _55 contained correct user information. Would every people help me figure out the problem and give me possible solution? Thank You!
Snapshot: Debugger snapshot
Reducer:
import {AsyncStorage} from "react-native";
import {LOGIN, LOGOUT, UPDATE} from './../actions/authActions'
import user from "./index";
export type State = {
user: Object,
login: boolean,
}
getUser = async (string) => { //Get user information form AsyncStorage
try {
return await AsyncStorage.getItem(string)
.then((user) => {
if (user !== null) {
return JSON.parse(user);
} else {
return null;
}
});
} catch (error) {
return null;
}
};
const initialState = {
info: getUser(),
login: !!this.info, // if not null, login = ture
};
function loginReducer(state: State = initialState, action) {
switch (action.type) {
case LOGIN:
return {
info: action.payload,
login: true,
};
case LOGOUT:
return {
info: null,
login: false,
};
case UPDATE:
return {...state, info: Object.assign(state.info, action.payload)};
default:
return state;
}
}
Action:
import {AsyncStorage} from "react-native";
import {requestLogIn, requestLogOut} from "../../config/api/authApi"
export const LOGIN = "LOGIN";
export const LOGOUT = "LOGOUT";
export const UPDATE = "UPDATE";
export const ERROR = "ERROR";
export function login(user) {
return dispatch => {
return AsyncStorage.setItem("user", JSON.stringify(user)) //Store user information in AsyncStorage
.then(() => {
dispatch({
type: LOGIN,
payload: user
})
}).catch((error) => {
console.warn("Error: ", error);
dispatch({
type: ERROR,
payload: null
})
});
}
}
export function logout(token) { //
return dispatch => {
return requestLogOut(token).then((status) => {
if (status) {
return AsyncStorage.removeItem("user")
.then(() => {
dispatch({
type: LOGOUT,
})
}).catch(() => {
dispatch({
type: ERROR,
payload: null
});
});
} else {
dispatch({
type: ERROR,
payload: null
});
}
})
}
} ..// other actions
Upvotes: 1
Views: 806
Reputation: 1074335
Your getUser
is an async
function, but you're not await
ing it:
const initialState = {
info: getUser(), // <=== here
login: !!this.info,
};
async
functions return promises.
Without getting into the broader context of the code too much, you probably want to do something like this:
const initialState = {
info: null,
login: !!this.info,
};
getUser().then(info => initialState.info = info);
Or something along those lines. Note that that means initialState.info
will be null
until the storage returns the value. If you have more initialization that needs that value, you'll have to trigger it from the then
handler above.
(No catch
on that because you've defined getUser
such that it cannot reject.)
Upvotes: 1