javascript - 如何处理 reducer 中的异步 promise

标签 javascript react-native redux react-redux

我是 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 获取初始数据。当您的应用加载时,使用 tokenprofile 键发送操作(您可以在根组件的 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/

相关文章:

javascript - 在函数内 react 运行函数

reactjs - 在 componentDidMount 中触发重新渲染

javascript - Ios Safari 的复制按钮

javascript - 我在更改输入值时遇到问题

javascript - 谷歌分析报告Reactjs

react-native - null 不是 React Native 组件中的对象(评估 'internalInstance.getHostNode' )

reactjs - react 生命周期 : phases

javascript - 在 React js 中根据 API 响应显示消息

javascript - 在两个具有其他id的div元素中具有具有相同id的两个元素是否正常?

javascript - AngularJS 在按键时移动滚动条