React onClick 路由仅有时有效

发布于 2025-01-12 14:16:10 字数 717 浏览 0 评论 0原文

这是视频证明。 https://dsc.cloud/leonardchoo/ Screen-Recording-2022-03-08-at-17.25.58.mov

我在单击按钮时遇到了一个神秘的错误对于导航,会触发“onClick”事件,但它不会重定向和呈现目标组件。

正如您在屏幕截图中看到的,onClick 事件已记录,但重定向并未发生。

中重现了这里的情况。

我在 CodeSandbox堆栈

  • React TS
  • Mantine UI
  • React Router V5

如何解决这个问题?

screenshotError

Here is the video proof.
https://dsc.cloud/leonardchoo/Screen-Recording-2022-03-08-at-17.25.58.mov

I'm running into a mysterious error where I click the button for navigation, "onClick" event is fired but it does not redirect and render the target component.

As you can see in the screenshot, the onClick event is logged, but the redirect does not happen.

I reproduced the situation here in CodeSandbox.

Stack

  • React TS
  • Mantine UI
  • React Router V5

How can I solve this issue?

screenshotError

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

卖梦商人 2025-01-19 14:16:10

我在代码中注意到的第一件事是,使用导航逻辑在每个路由组件周围渲染一个 WrapperPage 组件。我尝试尽可能简化 WrapperPage 代码。

采取的步骤:

  1. headernavbar 道具重构为独立组件,以防生成 JSX 时出现问题
  2. App< 中包装 Switch 组件/code> 使用单个 WrapperPage 而不是每个路由组件

问题仍然存在。

接下来,我从 @mantine/core 中删除了 UnstyledButton,因此仅渲染了 Link 组件,并且无法重现。然后我尝试了普通 HTML 按钮而不是 UnstyledButton,他们再次重现了该问题。

因此,在另一个交互式元素(按钮)中渲染交互式元素(即来自 Link 的锚标记)似乎是一个问题来自UnstyledButton)这是一个问题。交换元素顺序,即 Link 包装 UnstyledButton,似乎可以减少问题。我似乎无法用这种方式构建 DOM 来重现问题。

标题

const CustomHeader = ({
opened,
setOpened
}: {
opened: boolean;
setOpened: React.Dispatch<React.SetStateAction<boolean>>;
}) => {
const theme = useMantineTheme();

return (
<Header height={70} padding="md">
{/* Handle other responsive styles with MediaQuery component or createStyles function */}
<div style={{ display: "flex", alignItems: "center", height: "100%" }}>
<MediaQuery largerThan="sm" styles={{ display: "none" }}>
<Burger
opened={opened}
onClick={() => setOpened((o) => !o)}
size="sm"
color={theme.colors.gray[6]}
mr="xl"
/>
</MediaQuery>

<Group>
<ThemeIcon variant="light" color="orange">

First thing I noticed in your code was that is is rendering a WrapperPage component around each routed component with the navigation logic. I tried simplifying the WrapperPage code as much as possible.

Steps Taken:

  1. Refactored the header and navbar props into standalone components in case there was issue generating JSX
  2. Wrapped the Switch component in App with a single WrapperPage instead of each routed component

The issue persisted.

I next removed the UnstyledButton from @mantine/core so only the Link components were rendered, and could not reproduce. I then tried vanilla HTML buttons instead of the UnstyledButton and they again reproduced the issue.

So it seems it is an issue with rendering an interactive element (i.e. anchor tag from Link) within another interactive element (i.e. button from UnstyledButton) that is an issue. Swapping the element order, i.e. Link wrapping the UnstyledButton, appears to reduce the issue. I can't seem to reproduce the issue with the DOM structured this way.

Header

const CustomHeader = ({
  opened,
  setOpened
}: {
  opened: boolean;
  setOpened: React.Dispatch<React.SetStateAction<boolean>>;
}) => {
  const theme = useMantineTheme();

  return (
    <Header height={70} padding="md">
      {/* Handle other responsive styles with MediaQuery component or createStyles function */}
      <div style={{ display: "flex", alignItems: "center", height: "100%" }}>
        <MediaQuery largerThan="sm" styles={{ display: "none" }}>
          <Burger
            opened={opened}
            onClick={() => setOpened((o) => !o)}
            size="sm"
            color={theme.colors.gray[6]}
            mr="xl"
          />
        </MediaQuery>

        <Group>
          <ThemeIcon variant="light" color="orange">
            ????
          </ThemeIcon>
          <Text>Mantine AppShell with React Router</Text>
        </Group>
      </div>
    </Header>
  );
};

Navbar

const CustomNavbar = ({ opened }: { opened: boolean }) => {
  const location = useLocation();
  const { classes } = useStyles();

  return (
    <Navbar
      padding="md"
      // Breakpoint at which navbar will be hidden if hidden prop is true
      hiddenBreakpoint="sm"
      // Hides navbar when viewport size is less than value specified in hiddenBreakpoint
      hidden={!opened}
      // when viewport size is less than theme.breakpoints.sm navbar width is 100%
      // viewport size > theme.breakpoints.sm – width is 300px
      // viewport size > theme.breakpoints.lg – width is 400px
      width={{ sm: 300, lg: 400 }}
    >
      <Link
        to="/dashboard"
        className={classes.link}
      >
        <UnstyledButton
          className={
            location.pathname === "/dashboard"
              ? classes.button_active
              : classes.button
          }
        >
          <Group>
            <ThemeIcon variant="light">
              <DashboardIcon />
            </ThemeIcon>
            <Text size="sm">Dashboard</Text>
          </Group>
        </UnstyledButton>
      </Link>
      <Link
        to="/new-recording"
        className={classes.link}
      >
        <UnstyledButton
          className={
            location.pathname === "/new-recording"
              ? classes.button_active
              : classes.button
          }
        >
          <Group>
            <ThemeIcon variant="light" color="red">
              <RadiobuttonIcon />
            </ThemeIcon>

            <Text size="sm">New Recording</Text>
          </Group>
        </UnstyledButton>
      </Link>
      <Link
        to="/calendar"
        className={classes.link}
      >
        <UnstyledButton
          className={
            location.pathname === "/calendar"
              ? classes.button_active
              : classes.button
          }
        >
          <Group>
            <ThemeIcon variant="light" color="orange">
              <CalendarIcon />
            </ThemeIcon>

            <Text size="sm">Calendar</Text>
          </Group>
        </UnstyledButton>
      </Link>
    </Navbar>
  );
};

WrapperPage

const WrapperPage = ({ children }: Props): JSX.Element => {
  const [opened, setOpened] = useState(false);

  return (
    <AppShell
      // navbarOffsetBreakpoint controls when navbar should no longer be offset with padding-left
      navbarOffsetBreakpoint="sm"
      // fixed prop on AppShell will be automatically added to Header and Navbar
      fixed
      header={<CustomHeader opened={opened} setOpened={setOpened} />}
      navbar={<CustomNavbar opened={opened} />}
    >
      {children}
    </AppShell>
  );
};

Edit react-onclick-routing-only-works-sometimes

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文