如何在useEffect中调用useNavigate? - 用于 Ant Design 中的底部导航 - 移动

How to call useNavigate inside useEffect? - For bottom navigation in Ant Design - Mobile

我是 React 新手。我正在使用 AntD-mobile 制作一个应用程序。对于底部导航,我使用 tabBar Component in AntD-mobile。我不确定如何使用 Link 通过 TabBar 进行路由,在多次尝试失败后,我发现了 useNavigate.

const [navLink, setNavLink] = React.useState("/");
const navigate = useNavigate();
const redirect = useCallback(() => navigate(navLink, {replace: true}), [navigate]);

我想重定向到点击的任何选项卡,为此,我使用了 State,TabBar 的 onChange 首先更改状态并调用重定向。但是由于某种原因,加载了以前的状态。如果我在状态 1 并单击 2,它会保持在 1,当我单击 4 时,它会转到 2,依此类推。所以很可能,重定向在状态更改之前加载。 -

<TabBar onChange={(key)=>{setNavLink(key); redirect();}}>
      {tabs.map(item => (
            <TabBar.Item key={item.key} icon={item.icon} title={item.title}>
            </TabBar.Item>
      ))}
</TabBar>

为了解决这个问题,我尝试使用 useEffect(),其中我只更改 TabBar 的 onChange 中的状态,并在 useEffect 中调用重定向。但这不起作用。重定向无效。

useEffect(() => {
        redirect()
    }, [navLink]);

我做错了什么?如何在tabBar中设置底部导航?

问题

原始代码不起作用,因为 setNavLink(key); redirect(); 都发生在同一个渲染周期中。当调用 redirect 时,入队状态更新尚未处理,因此它仍然是先前状态的值。

onChange={(key) => {
  setNavLink(key); // <-- enqueued state update
  redirect();      // <-- navLink state not updated yet!
}}

解决方案

redirect 函数缺少依赖项,将 navLink 添加到依赖项数组将 re-enclose 更新后的 navLink 状态值。 useCallback(() => navigate(navLink, {replace: true}), [navigate]); 仅 computes/recomputes 初始渲染或依赖项更新时的回调。

const redirect = useCallback(
  () => navigate(navLink, { replace: true }),
  [navigate, navLink]
);

useEffect(() => {
  redirect()
}, [redirect]);

...

onChange={setNavLink}

您可以将 navLink 状态作为参数传入。

const redirect = useCallback(
  (navLink) => navigate(navLink, { replace: true }),
  [navigate]
);

useEffect(() => {
  redirect(navLink);
}, [navLink, redirect]);

...

onChange={setNavLink}

或者当 navLink 状态更新时,您可以直接在 useEffect 中使用 navigate

useEffect(() => {
  navigate(navLink, { replace: true });
}, [navLink]);

...

onChange={setNavLink}

或者直接在 onChange 处理程序中导航。

<TabBar onChange={(navLink) => navigate(navLink, { replace: true })}>
  {tabs.map(item => (
    <TabBar.Item
      key={item.key}
      icon={item.icon}
      title={item.title}
    />
  ))}
</TabBar>