reactjs - 动画反应路线不起作用零件
问题描述
我正在尝试为我的 React 应用程序构建一个简单的路由器,它包含从对象数组生成的一些路由和一个静态 404 路由。要求是每条路线之间的转换必须是动画的。
我正在使用react-router
浏览器和react-transition-group
.
我想实现这样的事情(精简,不完整的伪代码):
const routes = [
{ path: "/", component: Home },
{ path: "/about", component: About },
{ path: "/contact", component: Contact }
];
const createRoute = (route) => {
return (
<CSSTransition className="page" timeout={300}>
<Route path={route.path} exact component={route.component} />
</CSSTransition>
);
}
<Router>
{routes.map(createRoute)}
<CSSTransition className="page" timeout={300}>
<Route component={PageNotFound} />
</CSSTransition>
</Router>
可以在此 Codesandbox 上找到此代码的完整版本:
https://codesandbox.io/s/react-router-switch-csstransition-catch-all-route-bug-forked-qzt9g
我需要使用该<Switch>
组件来防止 404 路由显示在应用程序的所有其他路由中,但是一旦添加<Switch>
,动画就会停止工作。
在上面的示例中,您将看到动画在与 一起使用时不起作用<Switch>
,尽管遵循了官方文档中的指南react-router
和react-transition-group
。
但是,它们在不使用 的情况下完美地工作<Switch>
,但是当然我最终会一直显示 404 路线。
预期结果:
- 所有路由之间的动画转换,动态创建的以及静态 404 页面
实际结果:
- 根本没有动画或始终显示 404 路线的动画
我花了一整天的时间试图找到解决我遇到的问题的方法。不幸的是,我似乎找不到任何可以远程帮助我解决我面临的问题的东西,我已经在 Google、Stack Overflow、Medium 上进行了搜索,最后我回到了这里,希望有人能帮助我。
解决方案
为了让动画与 Switch 组件一起使用,您必须使用withRouter将正确的位置传递给CSSTransition以及TransitionGroup组件。我已经使用以下工作解决方案修改了您的沙箱代码:
import React from "react";
import ReactDOM from "react-dom";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import {
BrowserRouter as Router,
Route,
Switch,
Link,
withRouter
} from "react-router-dom";
import "./styles.css";
const rootElement = document.getElementById("root");
const components = {
Home: () => <div>Home page</div>,
About: () => <div>About the company</div>,
Contact: () => <div>Contact us</div>,
NotFound: () => <div>404</div>,
Menu: ({ links, setIsSwitch }) => (
<div className="menu">
{links.map(({ path, component }, key) => (
<Link key={key} to={path}>
{component}
</Link>
))}
<Link to="/404">404</Link>
</div>
)
};
const routes = [
{ path: "/", component: "Home" },
{ path: "/about", component: "About" },
{ path: "/contact", component: "Contact" }
];
const createRoutes = (routes) =>
routes.map(({ component, path }) => {
const Component = components[component];
const nodeRef = React.createRef();
return (
<Route key={path} path={path} exact>
{({ match }) => {
return (
<div ref={nodeRef} className="page">
<Component />
</div>
);
}}
</Route>
);
});
const AnimatedSwitch = withRouter(({ location }) => (
<TransitionGroup>
<CSSTransition
key={location.key}
timeout={500}
classNames="page"
unmountOnExit
>
<Switch location={location}>{createRoutes(routes)}</Switch>
</CSSTransition>
</TransitionGroup>
));
ReactDOM.render(
<React.StrictMode>
<Router>
<components.Menu links={routes} />
<AnimatedSwitch />
</Router>
</React.StrictMode>,
rootElement
);
本文详细解释了其背后的原因:https ://latteandcode.medium.com/react-how-to-animate-transitions-between-react-router-routes-7f9cb7f5636a 。
顺便说一句,在 react-router v6中不推荐使用withRouter。所以你应该自己实现那个钩子。
import { useHistory } from 'react-router-dom';
export const withRouter = (Component) => {
const Wrapper = (props) => {
const history = useHistory();
return (
<Component
history={history}
{...props}
/>
);
};
return Wrapper;
};
请参阅 GitHub 上已弃用的问题讨论:https ://github.com/remix-run/react-router/issues/7156 。
推荐阅读
- c++ - 如何抑制未使用的(void **arg)参数?
- javascript - `xhr.getAllHeaders()` 在浏览器扩展上下文中缺少一些标题?
- python - 如何按未排序的列表对数据框进行分组?
- excel - 单击边缘浏览器中的按钮
- git - 在 VSCode 中安装 git
- spring-boot - 具有多种身份验证方法的 Web 安全设置
- java - 如何在 Spring Data Elasticsearch 中为时间访问器的 HashMap 提供字段类型
- react-native - 部署时反应导航本机网络路由不起作用
- php - 如何使用 PHP 将 n 位数字随机排列到数组中?
- objective-c - 如何制作 dataWithEPSInsideRect 向量而不是向量格式的位图?