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

React-Native普通函数调用useSelector报Invalid hook call错误怎么解决

错误产生原因

React Hook有严格的调用规则,useSelector 属于Redux提供的自定义Hook,必须满足以下调用条件才可以正常执行:

  • 只能在React函数组件/自定义Hook的顶层作用域调用
  • 不能在普通JS函数、事件回调、异步逻辑、循环/条件判断内部调用

你写的authStage_getToken是普通工具函数,而且是在onButtonPress这个点击事件回调里触发调用的,完全不符合Hook的调用规则,因此触发Invalid hook call报错。而DetailsScreen里的useSelector是在函数组件的顶层调用,符合规则所以可以正常运行。


修复方案

方案1:把需要的Redux状态从组件传入工具函数(最推荐,符合单向数据流逻辑)

直接修改authStage_getToken,不要在内部调用Hook,改为接收username作为入参:

// authentication.js 修改后
export const authStage_getToken = (username) => {
    const password = 'testingEncoding';
    const credentials = base64.encode(username + ':' + password);
    console.log('authStage_getToken encoded credentials:', credentials);
    return credentials;
}

然后在LoginScreen组件内先拿到username再传入函数:

// LoginScreen.js 修改onButtonPress逻辑
const onButtonPress = () => {
  if (!username || username === '') {
    setValidationError("Username cannot be blank.");
    return;
  }
  changeLogin({username:username,password:password});
  console.log('Before triggering getToken...');
  // 直接把当前组件拿到的username传入
  const result = authStage_getToken(username);
  console.log('After triggering getToken, result: ', result);
}

方案2:非组件场景直接读取store实例

如果你的工具函数会在大量非组件场景调用,不方便每次传参,可以在你初始化Redux store的文件里把store实例导出,然后在工具函数里直接调用store.getState()拿状态:

// store初始化文件(示例,比如store.js)
import { configureStore } from '@reduxjs/toolkit';
import authenticationReducer from './reducers/authentication';

export const store = configureStore({
  reducer: {
    authentication: authenticationReducer,
    // 其他reducer
  }
})

修改authentication.js:

// authentication.js 修改后
import { store } from '../路径/到/你的/store.js';

export const authStage_getToken = () => {
    // 直接通过getState拿全局状态,不需要用Hook
    const username = store.getState().authentication.username;
    const password = 'testingEncoding';
    const credentials = base64.encode(username + ':' + password);
    console.log('authStage_getToken encoded credentials:', credentials);
    return credentials;
}

该方案不需要修改调用侧代码,注意getState是同步拿到调用瞬间的状态快照,不会自动监听状态变化,如果需要响应状态更新还是要在组件内使用useSelector。


内容的提问来源于stack exchange,提问作者Leland T Long

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:24:02