我是 redux 的新手,所以我想找出一个简单的身份验证用例示例。此代码的 Web 版本从 localstorage 获取初始状态并设置为 localstorage。将此示例转换为 react-native 意味着 localstorage 更改为异步的 AsyncStorage 并返回一个 promise 。
我如何处理 reducer 中的异步初始化器?
import { AsyncStorage } from 'react-native';
import {
LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_FAILURE, LOGOUT_SUCCESS,
} from '../actions/login';
const initialState = {
isFetching: false,
token: null, // AsyncStorage.getItem('token'),
profile: null, // AsyncStorage.getItem('profile'),
isLoggedIn: false,
errorMessage: null,
};
// The auth reducer. The starting state sets authentication
// based on a token in asyncstorage. In addition we would also null
// the token if we check that it's expired
export default (state = initialState, action) => {
switch (action.type) {
case LOGIN_REQUEST:
return Object.assign({}, state, {
isFetching: true,
isLoggedIn: false,
token: null,
user: null,
errorMessage: '',
});
case LOGIN_SUCCESS:
// todo set the async
// AsyncStorage.multiSet(['token', 'profile'], [action.token, action.profile])
return Object.assign({}, state, {
isFetching: false,
isLoggedIn: true,
token: action.token,
user: action.profile,
errorMessage: '',
});
case LOGIN_FAILURE:
return Object.assign({}, state, {
isFetching: false,
isLoggedIn: false,
token: null,
errorMessage: action.message,
});
case LOGOUT_SUCCESS:
// AsyncStorage.multiRemove(['token', 'profile'])
return Object.assign({}, state, {
isFetching: true,
isLoggedIn: false,
token: null,
});
default:
return state;
}
};
最佳答案
创建一个action creator 用于从 AsyncStorage 获取初始数据。当您的应用加载时,使用 token
或 profile
键发送操作(您可以在根组件的 componentDidMount
中执行此操作)。
// create similar actions creators for 'setItem' and 'multiSet' ops
export function loadLocalData(key) {
return {
types: [LOAD_LOCAL_DATA, LOAD_LOCAL_DATA_SUCCESS, LOAD_LOCAL_DATA_FAIL]
asyncStoragePromise: () => AsyncStorage.getItem(key),
key,
}
}
现在创建一个 middleware用于 AsyncStorage 操作。确保你 applyMiddleware
当您创建 store
时。
The most common use case for middleware is to support asynchronous actions without much boilerplate code or a dependency on a library like Rx. It does so by letting you dispatch async actions in addition to normal actions.
export default function asyncStorageMiddleware() {
return ({ dispatch, getState }) => next => (action) => {
if (typeof action === 'function') {
return action(dispatch, getState);
}
const { asyncStoragePromise, types, ...rest } = action;
if (!asyncStoragePromise) {
return next(action);
}
const [REQUEST, SUCCESS, FAILURE] = types;
next({ ...rest, type: REQUEST });
const actionPromise = asyncStoragePromise();
actionPromise
.then(result => next({ ...rest, result, type: SUCCESS }))
.catch(error => next({ ...rest, error, type: FAILURE }));
return actionPromise;
};
}
最后这是你的initialState:
const initialState = {
isFetching: false,
token: null,
profile: null,
isLoggedIn: false,
errorMessage: null,
localLoadErr: '',
};
和 reducer :
LOAD_LOCAL_DATA_SUCCESS:
return {
...state,
[action.key]: action.result,
};
break;
LOAD_LOCAL_DATA_FAIL:
return {
...state,
localLoadErr: action.error,
};
break;
关于javascript - 如何处理 reducer 中的异步 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40705162/