React onClick 路由仅在某些时候有效
React onClick routing ONLY works SOMETIMES
这是视频证明。
https://dsc.cloud/leonardchoo/Screen-Recording-2022-03-08-at-17.25.58.mov
我 运行 遇到了一个神秘的错误,我点击按钮进行导航,触发了“onClick”事件,但它没有重定向和呈现目标组件。
如您在屏幕截图中所见,记录了 onClick
事件,但没有发生重定向。
这里重现了这个情况
堆栈
- React TS
- 曼汀UI
- React Router V5
我该如何解决这个问题?
我在您的代码中注意到的第一件事是使用导航逻辑在每个路由组件周围呈现一个 WrapperPage
组件。我尝试尽可能地简化 WrapperPage
代码。
采取的步骤:
- 将
header
和 navbar
属性重构为独立组件,以防生成 JSX 时出现问题
- 用单个
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>
);
};
这是视频证明。 https://dsc.cloud/leonardchoo/Screen-Recording-2022-03-08-at-17.25.58.mov
我 运行 遇到了一个神秘的错误,我点击按钮进行导航,触发了“onClick”事件,但它没有重定向和呈现目标组件。
如您在屏幕截图中所见,记录了 onClick
事件,但没有发生重定向。
堆栈
- React TS
- 曼汀UI
- React Router V5
我该如何解决这个问题?
我在您的代码中注意到的第一件事是使用导航逻辑在每个路由组件周围呈现一个 WrapperPage
组件。我尝试尽可能地简化 WrapperPage
代码。
采取的步骤:
- 将
header
和navbar
属性重构为独立组件,以防生成 JSX 时出现问题 - 用单个
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>
);
};