Unable to use useSelector and useDispatch in export const function

61 Views Asked by At

I am unable to use useSelector and useDispatch in export const function.

export const StartTelecalling = (piopiy, userId, password) => {
  const { modal, isTestCall, isOnline } = useSelector((state) => state.calls);
  const dispatch = useDispatch();
  
  piopiy.login(userId, password, "sbcind.telecmi.com");
  console.log("login Initiated..............");
  piopiy.on("login", (object) => {
    console.log(object);
    // if (object.code === 200) {
    console.log("login successfully......");
    //   dispatch(setIsOnline(true));

    // }
  });
}

In the above code I am getting invalid hook call at useSelector and useDispatch and I have multiple exports like that I can't declare as default export.

2

There are 2 best solutions below

0
CoderCat On

You cannot call hooks inside nested functions, loops, conditions or regular JS functions as per React documentation. Also, React Hooks can only be called at the top level. Apparently, you are calling the hooks inside a regular JS function. Calling these hooks inside a functional react component might solve the issue.

0
Drew Reese On

Default export or not, you are breaking the Rules of Hooks:

Only Call Hooks at the Top Level

Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.

Only Call Hooks from React Functions

Don’t call Hooks from regular JavaScript functions. Instead, you can:

  • ✅ Call Hooks from React function components.
  • ✅ Call Hooks from custom Hooks

StartTelecalling is neither a React component nor a custom React hook.

You can either convert StartTelecalling into a custom React hook, basically just rename it to use the "use-" hook prefix naming convention, so that it can call other React hooks:

export const useStartTeleCalling = (piopiy, userId, password) => {
  const { modal, isTestCall, isOnline } = useSelector((state) => state.calls);
  const dispatch = useDispatch();
  
  return () => 
    piopiy.login(userId, password, "sbcind.telecmi.com");
    console.log("login Initiated..............");
    piopiy.on("login", (object) => {
      console.log(object);
      // if (object.code === 200) {
      console.log("login successfully......");
      //   dispatch(setIsOnline(true));

       // }
    });
  };
}
const startTeleCalling = useStartTeleCalling(piopiy, userId, password);

...

startTeleCalling();

Or refactor the function to have the selected state and dispatch function passed in as arguments.

export const startTeleCalling = ({
  piopiy,
  userId,
  password,
  modal,
  isTestCall,
  isOnline,
  dispatch
}) => {
  piopiy.login(userId, password, "sbcind.telecmi.com");
  console.log("login Initiated..............");
  piopiy.on("login", (object) => {
    console.log(object);
    // if (object.code === 200) {
    console.log("login successfully......");
    //   dispatch(setIsOnline(true));

     // }
  });
}
const { modal, isTestCall, isOnline } = useSelector((state) => state.calls);
const dispatch = useDispatch();

...

startTeleCalling({
  piopiy,
  userId,
  password,
  modal,      // <-- pass selected state
  isTestCall, // <-- pass selected state
  isOnline,   // <-- pass selected state
  dispatch    // <-- pass dispatch
});