如何将 React 中的 localStorage 代码转换为 React Native 中的 AsyncStorage?

How to convert localStorage code in React to AsyncStorage in React Native?

我想知道如何使用 AsyncStorage 将我的 React 代码转换为 React Native。我已经尝试了下面的代码,但是我得到了“isAuthenticated”的“未定义”以及“JSON.parse(AsyncStorage.getItem('token')”中的“错误”。我想使用“isAuthenticated”值仅显示组件的特定部分。

反应代码:

export const Auth = (state = {
        isLoading: false,
        isAuthenticated: localStorage.getItem('token') ? true : false,
        token: localStorage.getItem('token'),
        user: localStorage.getItem('creds') ? JSON.parse(localStorage.getItem('creds')) : null,
        errMess: null
    }, action) => {
    switch (action.type) {
        case ActionTypes.LOGIN_REQUEST:
            return {...state,
                isLoading: true,
                isAuthenticated: false,
                user: action.creds
            };
        case ActionTypes.LOGIN_SUCCESS:
            return {...state,
                isLoading: false,
                isAuthenticated: true,
                errMess: '',
                token: action.token
            };
        case ActionTypes.LOGIN_FAILURE:
            return {...state,
                isLoading: false,
                isAuthenticated: false,
                errMess: action.message
            };
        case ActionTypes.LOGOUT_REQUEST:
            return {...state,
                isLoading: true,
                isAuthenticated: true
            };
        case ActionTypes.LOGOUT_SUCCESS:
            return {...state,
                isLoading: false,
                isAuthenticated: false,
                token: '',
                user: null
            };
        default:
            return state
    }
}

我在 React Native 中的代码:

import * as ActionTypes from './ActionTypes';

// The auth reducer. The starting state sets authentication
// based on a token being in local storage. In a real app,
// we would also want a util to check if the token is expired.
export const auth = (state = {
  isLoading: false,
  isAuthenticated: false,
  token: null,
  user: null,
  errMess: null
}, action) => {
  switch (action.type) {
    case ActionTypes.GET_AUTH:
      return {
        ...state,
        ...action.payload
      };
    case ActionTypes.LOGIN_REQUEST:
      return {
        ...state,
        isLoading: true,
        isAuthenticated: false,
        user: action.creds
      };
    case ActionTypes.LOGIN_SUCCESS:
      return {
        ...state,
        isLoading: false,
        isAuthenticated: true,
        errMess: '',
        token: action.token
      };
    case ActionTypes.LOGIN_FAILURE:
      return {
        ...state,
        isLoading: false,
        isAuthenticated: false,
        errMess: action.message
      };
    case ActionTypes.LOGOUT_REQUEST:
      return {
        ...state,
        isLoading: true,
        isAuthenticated: true
      };
    case ActionTypes.LOGOUT_SUCCESS:
      return {
        ...state,
        isLoading: false,
        isAuthenticated: false,
        token: '',
        user: null
      };
    default:
      return state
  }
}

提前致谢。

编辑:这是我更新的代码。

export const getAuth = () => {
  return async(dispatch) => {
    const [token, creds] = await Promise.all([
      AsyncStorage.getItem('token'),
      AsyncStorage.getItem('creds')
    ])

    dispatch({
      type: ActionTypes.GET_AUTH,
      payload: {
        isLoading: false,
        isAuthenticated: !!token,
        token: token,
        user: JSON.parse(creds),
        errMess: null
      }
    });
  }
}

export const loginUser = (creds) => (dispatch) => {
  // We dispatch requestLogin to kickoff the call to the API
  dispatch(requestLogin(creds))

  return fetch(baseUrl + 'users/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(creds)
    })
    .then(response => {
        if (response.ok) {
          return response;
        } else {
          var error = new Error('Error ' + response.status + ': ' + response.statusText);
          error.response = response;
          throw error;
        }
      },
      error => {
        throw error;
      })
    .then(response => response.json())
    .then(response => {
      if (response.success) {
        async() => {
          try {
            await AsyncStorage.setItem('token', response.token);
            await AsyncStorage.setItem('creds', JSON.stringify(creds));
          } catch (error) {
            // Error saving data
          }
        }
        // If login was successful, set the token in local storage
        //AsyncStorage.setItem('token', response.token);
        //AsyncStorage.setItem('creds', JSON.stringify(creds));
        // Dispatch the success action
        dispatch(fetchSaves());
        dispatch(receiveLogin(response));
      } else {
        var error = new Error('Error ' + response.status);
        error.response = response;
        throw error;
      }
    })
    .catch(error => dispatch(loginError(error.message)))
};

AsyncStorage 是异步的。 使用

const value = await AsyncStorage.getItem('token');

我认为您应该将 initialState 保留为默认值,使用 redux-thunk 并在应用启动时分派一个操作以获取授权数据。

const getAuth = () => {
    return async (dispatch) => {
        const [token, user] = await Promise.all([
          AsyncStorage.getItem('token'),
          AsyncStorage.getItem('creds')
        ])

        dispatch({
          type: 'GET_AUTH',
          payload: {
            isLoading: false,
            isAuthenticated: !!token,
            token,
            user: JSON.parse(creds),
            errMess: null
          }
        });
    }
}

const App = connect({}, {getAuth})(({getAuth}) => {

  useEffect(() => {
    getAuth();
  }, [])
  
  return ...
})

export const auth = async (state = {
    isLoading: false,
    isAuthenticated: false,
    token: null,
    user: null,
    errMess: null
}, action) => {
    switch (action.type) {
        case ActionTypes.GET_AUTH:
            return {
                ...state,
                ...action.payload
            };
        ...
}

@Samir Kumar试试这个

import { AsyncStorage } from 'react-native';

async functionName(){
  const token = await AsyncStorage.getItem('token');
}