Search code examples
javascriptreactjsreact-hooksservicecomponents

How to call a hook from an exported function since it is not inside of the body of a function component


I cannot access my service class methods when I convert the export to service rather than methods:

const HttpService = () => {
  
  const AUTH_TOKEN = localStorage.getItem("tokenKey");
  const { enqueueSnackbar } = useSnackbar();

  const postWithoutAuth = (url, body) => {
    const request = axios.post(url, body);
    return request.then((response) => response.data);
  };
};

export default HttpService;

I am trying to access the postWithoutAuth method as shown below:

import { HttpService } from "../../services/HttpService";
// I think I should use like this:
import HttpService from "../../services/HttpService";

const handleSubmit = (event) => {
    event.preventDefault();
    HttpService.postWithoutAuth("/auth/signup", formValues)
      .then((response) => {})
      .catch((error) => {});
  };

So, is it a proper way to call this service method?


Solution

  • don't make HttpService a function but just a file in which you include all the functions you want to export :

    export const postWithoutAuth = (url, body) => {
      const request = axios.post(url, body);
      return request.then((response) => response.data);
    };
    export const anotherOne= (url, body) => {
      //...
    };
    

    Now you can import from it :

    import { postWithoutAuth, anotherOne } from "../../services/HttpService";
    

    Update to reply to the op question update:

    If you want to use a hook from the postWithoutAuth function then you pass a function to it from the parent component that uses the hook because

    hooks can only be called inside of the body of a function component

    export const postWithoutAuth = (url, body, functionHook) => {
      const request = axios.post(url, body);
      return request.then((response) => {
         response.data;
         functionHook();
      });
    };
    

    from the parent component :

    import { useSnackbar } from "notistack";
    import { postWithoutAuth } from "../../services/HttpService";
    
    const Parent = () => {
      
      const { enqueueSnackbar } = useSnackbar();
    
      const functionHook = () => {
        enqueueSnackbar("Failed to Login", {
          variant: "error",
        });
      };
    }
    
    <div>
      <button
        onClick={() => {
          postWithoutAuth(url, body, functionHook);
        }}
      >
        Click me
      </button>
    </div>;
    
    

    You can make multiple functions similar to the functionHook in your parent component that display different alerts and you can also pass more then one function the the postWithoutAuth function and based on the responde.data you know what function to execute