You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用loginUser时SecureStore未执行,直接返回axios.post结果问题排查

问题:loginUser函数未执行SecureStore相关逻辑,直接返回axios.post结果

我调用loginUser函数时,预期会执行SecureStore相关操作,但实际直接返回了axios.post方法的结果,未进入SecureStore的处理逻辑。请问问题出在哪里?

import { SecureStore } from 'expo';
export function loginUser(email, password) {
  return function (dispatch) {
    return axios.post(SIGNIN_URL, { email, password }).then((response) => {
      var { user_id, token } = response.data;
      Expo.SecureStore.setItemAsync(user_id, password, options).then(function() {
        dispatch(authUser(user_id));
        console.log('I am in')
      }).catch((error) => {
        console.log('Its an error')
        dispatch(addAlert("Could not log in."));
      });
    }).catch((error) => {
      dispatch(addAlert("Could not log in."));
    });
  };
}

问题分析与解决方案

咱们一步步拆解问题,找到根源:

1. SecureStore的引用不一致

你开头通过import { SecureStore } from 'expo'导入了SecureStore,但代码里却用了Expo.SecureStore——如果你的项目环境中没有全局挂载Expo对象,这会直接抛出引用错误,导致setItemAsync的逻辑根本无法执行,直接跳转到外层的catch块。

修复:统一使用导入的SecureStore:

SecureStore.setItemAsync(user_id, password, options)

2. 未返回SecureStore的Promise链

当前代码中,axios.post的then回调里执行了setItemAsync,但没有return这个Promise。这意味着loginUser返回的Promise会在axios.post完成后就立即resolve,而SecureStore的异步操作还在后台执行——你看到的“直接返回axios结果”就是这个原因,调用者会误以为整个流程已经完成,但SecureStore的逻辑其实还没跑完(甚至可能因为前面的错误根本没启动)。

修复:return setItemAsync的Promise链,让整个异步流程连贯起来:

return axios.post(SIGNIN_URL, { email, password }).then((response) => {
  var { user_id, token } = response.data;
  // 这里加上return,把SecureStore的Promise链传递出去
  return SecureStore.setItemAsync(user_id, password, options).then(function() {
    dispatch(authUser(user_id));
    console.log('I am in')
  }).catch((error) => {
    console.log('Its an error', error) // 打印具体错误信息,方便排查
    dispatch(addAlert("Could not log in."));
  });
})

3. options变量未定义

你调用setItemAsync时传入了第三个参数options,但代码里完全没有定义这个变量。这会导致参数错误,触发setItemAsync的catch块,虽然你有错误处理,但这也是SecureStore逻辑未按预期执行的潜在问题。

修复:如果不需要额外存储选项,直接去掉这个参数;如果需要自定义存储规则,先定义options:

// 方案1:不需要额外选项时去掉参数
return SecureStore.setItemAsync(user_id, password).then(...)

// 方案2:定义options(比如设置iOS钥匙串的访问权限)
const options = {
  keychainAccessible: SecureStore.WHEN_UNLOCKED
};
return SecureStore.setItemAsync(user_id, password, options).then(...)

修复后的完整代码

import { SecureStore } from 'expo';
import axios from 'axios'; // 确保导入axios,假设SIGNIN_URL、authUser、addAlert均已正确定义

export function loginUser(email, password) {
  return function (dispatch) {
    return axios.post(SIGNIN_URL, { email, password })
      .then((response) => {
        const { user_id, token } = response.data;
        // 可选:定义存储选项
        const options = {
          keychainAccessible: SecureStore.WHEN_UNLOCKED
        };
        // 返回SecureStore的Promise链,保证流程完整
        return SecureStore.setItemAsync(user_id, password, options)
          .then(() => {
            dispatch(authUser(user_id));
            console.log('I am in');
          })
          .catch((error) => {
            console.log('SecureStore操作错误:', error); // 打印具体错误
            dispatch(addAlert("无法保存登录凭证,请重试。"));
          });
      })
      .catch((error) => {
        console.log('登录请求错误:', error); // 打印请求错误细节
        dispatch(addAlert("登录失败,请检查账号密码或网络连接。"));
      });
  };
}

另外,建议在所有catch块中打印具体错误信息,这样能快速定位到底是请求失败、SecureStore操作失败还是其他语法问题。


内容的提问来源于stack exchange,提问作者Markus Hayner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:27:12