skip to Main Content

I have this function i want to implement multiple times which is why im trying to make it reusable. The problem is that useNavigate dosent seem to work inside it. And i dont really understand why

Here is the function

import { useNavigate } from "react-router-dom"

export async function UpdateTrashcan(messagedata, itemID, folder) {
    await fetch(
        "url/trashcan/" + (itemID) + ".json",
        {
            method: "PUT",
            body: JSON.stringify(messagedata),
            headers:{
                "Content-Type": "application/json"
            }
        }
        )
        await fetch(
            "url/" + (folder) + "/" + (itemID) + ".json",
            {   
                method: "DELETE",
                body: JSON.stringify(messagedata),
                headers:{
                    "Content-Type": "application/json"
                }
            }
        )
        useNavigate(0);
}

the console says its an Invalid hook call

5

Answers


  1. this is how you use useNavigate:

    export async function yourFunction(){
    // write your code here
    return true;
    }
    

    and then in the component do this:

    export default function SomeComponent(){
    let navigate = useNavigate()
    const func = async()=>{
    const result = await yourFunction();
    if(result) navigate(0)
    }
    useEffect(()=>{
    func()
    },[])
    return (<> <div></div> <>)
    
    Login or Signup to reply.
  2. You can pass variables from the hook to your functions. This also includes state setters and similar hook stuff.

    const MyComponent = () => {
    //Get variable in component from the hook
    const navigate = useNavigate()
    
    //use effect is not important. You can do it on button click too
    useEffect(() => {
    //Pass navigate to your function
    UpdateTrashcan("My message", "myId", "folderName", navigate)
    }, [])
    
    
    return (<p>My component</p>)
    }
    
    export async function UpdateTrashcan(messagedata, itemID, folder, navigate) {
        await fetch(
            //...)
            navigate("Whatever goes here");
    }
    
    
    Login or Signup to reply.
  3. You just can’t do this as a hook can be only called from a component or other hook, but that useNavigate hook just returns some value so that you can pass it as a normal argument. So all in all to make it working, in the component top-level code:

    const navigate = useNaviagate()

    And use it like this:

    UpdateTrashcan(messagedata, itemID, folder, navigate);
    

    And ofc function body has to be changed as well

    export async function UpdateTrashcan(messagedata, itemID, folder, navigate) {
        await fetch(
            "url/trashcan/" + (itemID) + ".json",
            {
                method: "PUT",
                body: JSON.stringify(messagedata),
                headers:{
                    "Content-Type": "application/json"
                }
            }
            )
            await fetch(
                "url/" + (folder) + "/" + (itemID) + ".json",
                {   
                    method: "DELETE",
                    body: JSON.stringify(messagedata),
                    headers:{
                        "Content-Type": "application/json"
                    }
                }
            )
           navigate(WHERE);
    }
    
    

    But that passing of an argument is a little stinky, as it’s clearly mixing responsibilities, and reusable code like that shouldn’t know anything about redirecting, so it should be handled one layer above in the component code, like that:

    try {
      await UpdateTrashcan(messagedata, itemID, folder);
      // if we succeed
      navigate(WHERE)
    } catch (e) {
      // handle errors
    }
    
    
    Login or Signup to reply.
  4. As your reusable function has nothing to do with React stuffs, useNavigate Hook can Not be used there. React Router’s official docs suggests for these cases to use redirect instead of useNavigate.

    As a result you can change the logic like this:

    import { redirect } from "react-router-dom"
    
    export async function updateTrashcan(messagedata, itemID, folder) {
        await fetch(
            "url/trashcan/" + (itemID) + ".json",
            {
                method: "PUT",
                body: JSON.stringify(messagedata),
                headers:{
                    "Content-Type": "application/json"
                }
            }
            )
            await fetch(
                "url/" + (folder) + "/" + (itemID) + ".json",
                {   
                    method: "DELETE",
                    body: JSON.stringify(messagedata),
                    headers:{
                        "Content-Type": "application/json"
                    }
                }
            )
            redirect("where you want to go");
    }
    
    Login or Signup to reply.
  5. Hooks like useNavigate have to be used according to react rules.

    useNavigate is a React Hook, so it can/should only be called in specific ways.
    If you check the documentation about react hooks here, it might give you that error because you are probably calling the hook from a "normal" javaScript function.
    And that does against React’s hook usage.

    The function might not be recognized by react, because of missing imports, as is stated in the previous answer.

    Or it’s just the case of using the hook in the right place, which is, inside a react function or in a custom hook of yours.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search