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

求助:无法在export const函数中使用useSelector和useDispatch

解决React中普通函数无法使用useSelector/useDispatch的问题

React的Hook(包括useSelector、useDispatch)有严格的调用规则:只能在React函数组件的顶层或者自定义Hook的顶层调用,普通工具函数里调用会触发「无效钩子调用」错误。你的StartTelecalling是普通导出函数,不符合Hook的使用条件,下面给两种适配方案:

方案一:将函数改为自定义Hook

自定义Hook必须以use开头命名,React会识别它是Hook并允许内部调用其他Hook,同时支持命名导出(满足你多个导出的需求)。

修改后的代码:

// 自定义Hook,命名以use开头
export const useStartTelecalling = (piopiy, userId, password) => {
  const { modal, isTestCall, isOnline } = useSelector((state) => state.calls);
  const dispatch = useDispatch();
  
  // 封装实际执行逻辑的函数
  const startTelecalling = () => {
    piopiy.login(userId, password, "sbcind.telecmi.com");
    console.log("login Initiated..............");
    piopiy.on("login", (object) => {
      console.log(object);
      console.log("login successfully......");
      if (object.code === 200) {
        dispatch(setIsOnline(true));
      }
    });
  };

  // 返回执行函数供组件调用
  return startTelecalling;
};

在React组件中使用:

import { useStartTelecalling } from './your-file-path';

function YourComponent() {
  // 从Hook拿到执行函数
  const startTelecalling = useStartTelecalling(piopiy, userId, password);

  return (
    <button onClick={startTelecalling}>开始呼叫</button>
  );
}

方案二:将dispatch和状态作为参数传入函数

如果不想改成Hook,可以在组件中先获取dispatch和需要的状态,再作为参数传递给普通工具函数,让函数本身脱离对React Hook的依赖。

修改后的代码:

// 普通工具函数,接收外部传入的dispatch和状态
export const StartTelecalling = (piopiy, userId, password, dispatch, callsState) => {
  const { modal, isTestCall, isOnline } = callsState;
  
  piopiy.login(userId, password, "sbcind.telecmi.com");
  console.log("login Initiated..............");
  piopiy.on("login", (object) => {
    console.log(object);
    console.log("login successfully......");
    if (object.code === 200) {
      dispatch(setIsOnline(true));
    }
  });
};

在React组件中使用:

import { StartTelecalling } from './your-file-path';
import { useSelector, useDispatch } from 'react-redux';

function YourComponent() {
  const callsState = useSelector((state) => state.calls);
  const dispatch = useDispatch();

  const handleStart = () => {
    // 传入dispatch和状态
    StartTelecalling(piopiy, userId, password, dispatch, callsState);
  };

  return (
    <button onClick={handleStart}>开始呼叫</button>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 22:45:08