如何在可重复使用的函数中使用导航?

huangapple go评论75阅读模式
英文:

How to useNavigate in a reusable function?

问题

我有这个函数,我想要多次实现它,这就是为什么我试图使它可重用的原因。问题是```useNavigate```似乎在其中不起作用。我不太明白为什么

这是函数
```javascript
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);
}

控制台显示它是一个无效的钩子调用


<details>
<summary>英文:</summary>

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

</details>


# 答案1
**得分**: 1

你可以从钩子传递变量到你的函数中,这也包括状态设置器和类似的钩子功能。

```jsx
const MyComponent = () => {
  // 从钩子中获取组件中的变量
  const navigate = useNavigate();

  // 使用效果不重要,你也可以在按钮点击时执行它
  useEffect(() => {
    // 将 navigate 传递给你的函数
    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")
  );
}
英文:

You can pass variables from the hook to your functions. This also includes state setters and similar hook stuff.

const MyComponent = () =&gt; {
//Get variable in component from the hook
const navigate = useNavigate()

//use effect is not important. You can do it on button click too
useEffect(() =&gt; {
//Pass navigate to your function
UpdateTrashcan(&quot;My message&quot;, &quot;myId&quot;, &quot;folderName&quot;, navigate)
}, [])


return (&lt;p&gt;My component&lt;/p&gt;)
}
export async function UpdateTrashcan(messagedata, itemID, folder, navigate) {
    await fetch(
        //...)
        navigate(&quot;Whatever goes here&quot;);
}

答案2

得分: 1

你只需要翻译代码部分,以下是已翻译的内容:

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
}
英文:

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(
        &quot;url/trashcan/&quot; + (itemID) + &quot;.json&quot;,
        {
            method: &quot;PUT&quot;,
            body: JSON.stringify(messagedata),
            headers:{
                &quot;Content-Type&quot;: &quot;application/json&quot;
            }
        }
        )
        await fetch(
            &quot;url/&quot; + (folder) + &quot;/&quot; + (itemID) + &quot;.json&quot;,
            {   
                method: &quot;DELETE&quot;,
                body: JSON.stringify(messagedata),
                headers:{
                    &quot;Content-Type&quot;: &quot;application/json&quot;
                }
            }
        )
       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
}

答案3

得分: 0

这是如何使用useNavigate:

export async function yourFunction(){
  // 在这里编写你的代码
  return true;
}

然后在组件中这样做:

export default function SomeComponent(){
  let navigate = useNavigate()
  const func = async() => {
    const result = await yourFunction();
    if(result) navigate(0)
  }
  useEffect(() => {
    func()
  }, [])
  return (<></>)
}
英文:

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()=&gt;{
const result = await yourFunction();
if(result) navigate(0)
}
useEffect(()=&gt;{
func()
},[])
return (&lt;&gt; &lt;div&gt;&lt;/div&gt; &lt;&gt;)

答案4

得分: 0

Your reusable function与React无关, useNavigate Hook不能在那里使用。React Router官方文档建议在这些情况下使用redirect而不是useNavigate

因此,您可以像这样更改逻辑:

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("您要前往的位置");
}
英文:

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 &quot;react-router-dom&quot;

export async function updateTrashcan(messagedata, itemID, folder) {
    await fetch(
        &quot;url/trashcan/&quot; + (itemID) + &quot;.json&quot;,
        {
            method: &quot;PUT&quot;,
            body: JSON.stringify(messagedata),
            headers:{
                &quot;Content-Type&quot;: &quot;application/json&quot;
            }
        }
        )
        await fetch(
            &quot;url/&quot; + (folder) + &quot;/&quot; + (itemID) + &quot;.json&quot;,
            {   
                method: &quot;DELETE&quot;,
                body: JSON.stringify(messagedata),
                headers:{
                    &quot;Content-Type&quot;: &quot;application/json&quot;
                }
            }
        )
        redirect(&quot;where you want to go&quot;);
}

答案5

得分: 0

Hooks like useNavigate have to be used according to react rules.

useNavigate是一个React Hook,所以它只能以特定的方式调用。
如果您查看有关React钩子的文档此处,可能会出现错误,因为您可能是从“普通”的JavaScript函数中调用该钩子。
这违反了React的钩子用法。

可能是因为缺少导入而导致React无法识别该函数,正如前一个答案中所述。

或者只是在正确的地方使用钩子,即在React函数内部或在您自己的自定义钩子中。

英文:

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.

huangapple
  • 本文由 发表于 2023年6月27日 19:24:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76564364.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定