React onClick 路由仅在某些时候有效

React onClick routing ONLY works SOMETIMES

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

我 运行 遇到了一个神秘的错误,我点击按钮进行导航,触发了“onClick”事件,但它没有重定向和呈现目标组件。

如您在屏幕截图中所见,记录了 onClick 事件,但没有发生重定向。

我在CodeSandbox.

这里重现了这个情况

堆栈

我该如何解决这个问题?

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

采取的步骤:

  1. headernavbar 属性重构为独立组件,以防生成 JSX 时出现问题
  2. 用单个 WrapperPage 包装了 App 中的 Switch 组件,而不是每个路由组件

问题仍然存在。

接下来,我从 @mantine/core 中删除了 UnstyledButton,因此只有 Link 组件被渲染,无法重现。然后我尝试了香草 HTML 按钮而不是 UnstyledButton,他们再次重现了这个问题。

因此,在另一个交互元素(button 来自 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">
            
          </ThemeIcon>
          <Text>Mantine AppShell with React Router</Text>
        </Group>
      </div>
    </Header>
  );
};

导航栏

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>
  );
};

包装页面

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>
  );
};