求助:无法在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
相关产品推荐
相关产品推荐

