确定已解析的路由。

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

Determine Which Route Was Resolved

问题

给定这样的路由:

<Routes>
  <Route element={<MainLayout />}>
    <Route path="foo/:token" element={<Foo />} />
    <Route path=":token" element={<Bar />}>
      <Route path=":id" element={<Baz />} />
    <Route>
  </Route>
</Routes>

MainLayout 如何知道哪个路由已解析?我需要知道它是否在具有 path=":token" 的路由树内。

useMatch('/:token/*') 不起作用,因为它匹配到路径 foo/123,这将解析为 path="foo/:token" 路由。

我弄不清楚 useResolvedPath 做什么或者我如何使用它。它似乎只是回显输入参数。

我不能使用 const { token } = useParams(),因为这两个路由都有名为 token 的参数。

有什么想法吗?

英文:

Given routes like this:

&lt;Routes&gt;
  &lt;Route element={&lt;MainLayout /&gt;}&gt;
    &lt;Route path=&quot;foo/:token&quot; element={&lt;Foo /&gt;} /&gt;
    &lt;Route path=&quot;:token&quot; element={&lt;Bar /&gt;}&gt;
      &lt;Route path=&quot;:id&quot; element={&lt;Baz /&gt;}&gt;
    &lt;Route&gt;
  &lt;/Route&gt;
&lt;/Routes&gt;

How can MainLayout know which route was resolved? I need to know if it was within the route tree with path=&quot;:token&quot;.

useMatch(&#39;/:token/*&#39;) does not work because it matches on path foo/123, which resolves to the path=&quot;foo/:token&quot; route.

I can't figure out what useResolvedPath does or how I could use it. I just seems to echo the input param.

I can't use const { token } = useParams() since both routes have a param named token.

Ideas?

答案1

得分: 1

看起来问题或者疑问实际上是关于如何区分两个定义了相同路径参数变量的路由。换句话说,您试图检查token路径参数是从哪个路由填充而来。

我在这里的建议是使用不同的路径参数变量名称来消除歧义。

例如,使用fooTokenbarToken

<Routes>
  <Route element={<MainLayout />}>
    <Route path="foo/:fooToken" element={<Foo />} />
    <Route path=":barToken" element={<Bar />}>
      <Route path=":id" element={<Baz />} />
    <Route>
  </Route>
</Routes>

MainLayout 组件可以检查这两者并有条件地应用逻辑。

const { barToken, fooToken } = useParams();

...

useEffect(() => {
  if (barToken) {
    // bar token 逻辑
  }

  if (fooToken) {
    // foo token 逻辑
  }

}, [barToken, fooToken]);
...

另一种方法是使用 useMatch 钩子,显式地检查每个具有 token 路径参数的路由是否匹配。

const MainLayout = () => {
  const fooMatch = useMatch("/foo/:token"); // foo token
  const barMatch = useMatch("/:token");     // bar token
  const bazMatch = useMatch("/:token/:id"); // bar token

  useEffect(() => {
    console.log({ fooMatch, barMatch, bazMatch });

    if (barMatch || bazMatch) {
      // bar token 逻辑
    }

    if (fooMatch) {
      // foo token 逻辑
    }

  }, [fooMatch, barMatch, bazMatch]);

  return (
    <>
      ...
      <Outlet />
    </>
  );
};
英文:

It seems the issue, or question, is really about how to differentiate between the two routes that defined identical path parameter variables. In other words, you are trying to check which route the token path param was populated from.

My suggestion here would be to use different path parameter variable names to disambiguate them.

For example fooToken and barToken:

&lt;Routes&gt;
  &lt;Route element={&lt;MainLayout /&gt;}&gt;
    &lt;Route path=&quot;foo/:fooToken&quot; element={&lt;Foo /&gt;} /&gt;
    &lt;Route path=&quot;:barToken&quot; element={&lt;Bar /&gt;}&gt;
      &lt;Route path=&quot;:id&quot; element={&lt;Baz /&gt;}&gt;
    &lt;Route&gt;
  &lt;/Route&gt;
&lt;/Routes&gt;

The MainLayout component can check for both and conditionally apply logic.

const { barToken, fooToken } = useParams();

...

useEffect(() =&gt; {
  if (barToken) {
    // bar token logic
  }

  if (fooToken) {
    // foo token logic
  }

}, [barToken, fooToken]);
...

An alternative would be to use the useMatch hook and explicitly check for a match for each route that has a token path parameter.

const MainLayout = () =&gt; {
  const fooMatch = useMatch(&quot;/foo/:token&quot;); // foo token
  const barMatch = useMatch(&quot;/:token&quot;);     // bar token
  const bazMatch = useMatch(&quot;/:token/:id&quot;); // bar token

  useEffect(() =&gt; {
    console.log({ fooMatch, barMatch, bazMatch });

    if (barMatch || bazMatch) {
      // bar token logic
    }

    if (fooMatch) {
      // foo token logic
    }

  }, [fooMatch, barMatch, bazMatch]);

  return (
    &lt;&gt;
      ...
      &lt;Outlet /&gt;
    &lt;/&gt;
  );
};

答案2

得分: 0

我想错了,我的问题没有充分解释上下文。

MainLayout 包含全局导航元素,我希望针对不同的路由稍作调整。而不是让 MainLayout 朝外查看路由,路由设置应该告诉 MainLayout 要做什么。像这样:

&lt;Routes&gt;
  &lt;Route element={&lt;MainLayout /&gt;}&gt;
    &lt;Route path=&quot;foo/:token&quot; element={&lt;Foo /&gt;} /&gt;
  &lt;/Route&gt;
  &lt;Route element={&lt;MainLayout someParam={paramValue} /&gt;}&gt;
    &lt;Route path=&quot;:token&quot; element={&lt;Bar /&gt;}&gt;
      &lt;Route path=&quot;:id&quot; element={&lt;Baz /&gt;}&gt;
    &lt;Route&gt;
  &lt;/Route&gt;
&lt;/Routes&gt;

MainLayout 使用 paramValue 以实现不同的行为。

英文:

I was thinking about this wrong, and my question did not explain the context well enough to spot it.

MainLayout contains global nav elements that I want to be slightly different for different routes. Rather than have MainLayout look outward at the route, the router setup should tell MainLayout what to do. Like this:

&lt;Routes&gt;
  &lt;Route element={&lt;MainLayout /&gt;}&gt;
    &lt;Route path=&quot;foo/:token&quot; element={&lt;Foo /&gt;} /&gt;
  &lt;/Route&gt;
  &lt;Route element={&lt;MainLayout someParam={paramValue} /&gt;}&gt;
    &lt;Route path=&quot;:token&quot; element={&lt;Bar /&gt;}&gt;
      &lt;Route path=&quot;:id&quot; element={&lt;Baz /&gt;}&gt;
    &lt;Route&gt;
  &lt;/Route&gt;
&lt;/Routes&gt;

Where MainLayout uses paramValue to behave differently.

huangapple
  • 本文由 发表于 2023年6月9日 00:55:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76434127.html
匿名

发表评论

匿名网友

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

确定