我偶然发现了AsyncStorage的一种奇怪的行为,我无法把头绕在头上,我会感激任何人能向我解释幕后发生了什么(即失败的案例和原因)。
下面是我正在研究的代码:
componentDidMount() {
let _this = this;
AsyncStorage.getItem('token', (err, data) => {
setTimeout(() => {
if(data !== null){
this.setState({isReady: true, isLoggedIn: true});
store.dispatch({type: t.LOGGED_IN, token: data});
}
else{
this.setState({isReady: true, isLoggedIn: false})
store.dispatch({type: t.LOGGED_OUT});
}
}, 3000)
console.log(err);
});
}正如您所看到的,我正在按照文档将一个callback函数传递给getItem(),这基本上告诉我用户以前是否登录过并且此后还没有注销(也就是说,令牌仍然在设备/应用程序中的某个位置)。这段代码第一次成功,检索了我通过减法器存储的旧令牌:
export default function authReducer(state = initialState, action)
{
switch (action.type) {
case t.LOGGED_IN:{
AsyncStorage.setItem('token', action.token);
return Object.assign({}, state, { isLoggedIn: true, token: action.token });
}
case t.LOGGED_OUT:{
AsyncStorage.removeItem('token');
return Object.assign({}, state, {isLoggedIn: false, token: null});
}
default:
return state;
}
}然而,在我第二次重新加载应用程序时,即使我一次又一次地尝试登录,AsyncStorage也总是无法检索数据。
我也尝试了AsyncStorage调用的变体,即使用await、.then和.catch,但是它们都导致了相同的结果。
我的问题是:
getItem()仍然会调用我传递的回调函数,因为param列表上有一个error。但是,在上述情况下,我的console.log从未运行过。我在等什么不该在这里的事吗?setItem()而不删除它将导致存储失败?(我确信第一次尝试是成功的,因为我从异步存储中打印了检索到的令牌)谢谢!)
编辑:经过进一步的检查,似乎停止了打包程序并再次运行它似乎允许应用程序再次成功地检索旧令牌,但是如果我再次刷新应用程序,在编辑代码之后,getItem()将再次失败。这是一个世博和持久存储的东西吗?
发布于 2018-05-04 06:31:30
发布于 2018-05-04 02:09:13
所以这个问题现在已经解决了,多亏了我的一个更有经验的程序员朋友。结果我的错误是我把AsyncStorage.setItem()调用放进了减速机,他说它本质上是deterministic。在调度之前,我将调用转移到该类的actions.js,它可以工作!
所以而不是
export default function authReducer(state = initialState, action)
{
switch (action.type) {
case t.LOGGED_IN:{
AsyncStorage.setItem('token', action.token);
return Object.assign({}, state, { isLoggedIn: true, token: action.token });
}
case t.LOGGED_OUT:{
AsyncStorage.removeItem('token');
return Object.assign({}, state, {isLoggedIn: false, token: null});
}
default:
return state;
}
}我做到了
export default function authReducer(state = initialState, action)
{
switch (action.type) {
case t.LOGGED_IN:{
return Object.assign({}, state, { isLoggedIn: true, token: action.token });
}
case t.LOGGED_OUT:{
return Object.assign({}, state, {isLoggedIn: false, token: null});
}
default:
return state;
}
}再加上这个
export function login(data, successCB, errorCB) {
return (dispatch) => {
api.login(data, function (success, data, error) {
if (success && data.exists) {
AsyncStorage.setItem('token', data.token); //NOTE THIS
dispatch({type: t.LOGGED_IN, token: data.token});
successCB(data);
}else if (error) errorCB(error)
});
};
}
export function signOut(successCB, errorCB){
return (dispatch) => {
AsyncStorage.removeItem('token'); //NOTE THIS
dispatch({type: t.LOGGED_OUT});
successCB();
}
}但我的问题仍然是persists (请原谅双关语),“为什么这个简单的修改有效?我是否理解reducers和dispatchers的错误机制?”
另外,deterministic意味着什么,与Async调用的不兼容有什么关系?
如果有人能向我解释这个概念,那就太棒了!:D
https://stackoverflow.com/questions/50149783
复制相似问题