React 404页面不适用于CSSTransition

时间:2019-08-18 11:57:22

标签: reactjs react-router reactcsstransitiongroup

我需要使用CSSTransition将404错误页面应用于ReactJs。当我将其与 react-router-dom交换机一起使用时,此方法工作正常。但是,我需要使用React Router实现CSSTransition。 http://reactcommunity.org/react-transition-group/with-react-router的想法。代码如下,

import React from 'react';
import { Route } from 'react-router-dom';
import { CSSTransition } from 'react-transition-group';

import InvalidPage from './InvalidPage';
import Dashboard from './Dashboard';
import Users from './Users';
import UserNew from './UserNew';

const routes = [
  { path: '/admin/dashboard', name: 'Dashboard', Component: Dashboard },
  { path: '/admin/user', name: 'Users', Component: Users },
  { path: '/admin/new-user', name: 'Add New User', Component: UserNew }
  { path: '/admin/404', name: '404 Error', Component: InvalidPage }
]

function SiteRoutes() {
  return(
    routes.map(({ path, Component }) => (
      <Route key={path} exact path={path}>
        {
          ({ match }) => (
            <CSSTransition
              in={match != null}
              timeout={300}
              classNames="page"
              unmountOnExit>
              <div className="page">
                <Component />
                {console.log(match != null)}
              </div>
            </CSSTransition>
          )
        }
      </Route>
    ))
  );
}

export default SiteRoutes;

当我单击未定义的路由(例如/ admin / edit-user)时,它将显示空白页面。但是,我需要一个404页面。

3 个答案:

答案 0 :(得分:1)

确保在响应中包含404页面的两件事是:

exact = {false}
path =“ *”
该组件应类似于<Route path="*" component={NotFoundComponent} />

https://reactrouter.com/web/example/no-match

注意:如果我不理解问题陈述,请在评论中让我知道。

这会将所有未知/未注册的路由重定向到您的404组件。

import React from 'react';
import { Route } from 'react-router-dom';
import { CSSTransition } from 'react-transition-group';

import InvalidPage from './InvalidPage';
import Dashboard from './Dashboard';
import Users from './Users';
import UserNew from './UserNew';

const routes = [
  { path: '/admin/dashboard', name: 'Dashboard', Component: Dashboard },
  { path: '/admin/user', name: 'Users', Component: Users },
  { path: '/admin/new-user', name: 'Add New User', Component: UserNew }
  { path: '/admin/404', name: '404 Error', Component: InvalidPage },
  { path: '*', name: '404 Error', Component: InvalidPage }
]

function SiteRoutes() {
  return(
    routes.map(({ path, Component }) => (
      <Route key={path} exact={path!=="*"} path={path}>
        {
          ({ match }) => (
            <CSSTransition
              in={match != null}
              timeout={300}
              classNames="page"
              unmountOnExit>
              <div className="page">
                <Component />
                {console.log(match != null)}
              </div>
            </CSSTransition>
          )
        }
      </Route>
    ))
  );
}

export default SiteRoutes;

答案 1 :(得分:0)

它在/admin/edit-user上显示空白页,因为此路由与您定义的任何路径都不匹配。

您需要为此添加一个空路径。原因:

  

没有路径的<Route>将始终匹配。

因此,请在末尾添加此路由<Route component={InvalidPage} />,以便当用户转到未定义的路由,例如/admin/edit-user/时,此空路由将匹配,并且将呈现InvalidPage组件。

还将所有路由都包装在Switch中,以便仅第一个匹配的路由匹配。如果没有Switch,则可以匹配多个路由,我认为这是不希望的。

答案 2 :(得分:0)

我也正在使用该代码示例。

这似乎有些矫kill过正(例如,必须有更好的方法),但是我能够抓住所有路线的唯一方法是使最后一个Route与支持的路径进行比较。

编辑:更改了我的代码示例以匹配OP。
编辑2:修正错误;经过测试的代码

import React from "react";
import { Route } from "react-router-dom";
import { CSSTransition } from "react-transition-group";

import InvalidPage from "./InvalidPage";
import Dashboard from "./Dashboard";
import Users from "./Users";
import UserNew from "./UserNew";

const routes = [
  { path: "/admin/dashboard", name: "Dashboard", Component: Dashboard },
  { path: "/admin/user", name: "Users", Component: Users },
  { path: "/admin/new-user", name: "Add New User", Component: UserNew }
];

function SiteRoutes() {
  const routeComponents = routes.map(({ path, Component }) => (
    <Route key={path} exact path={path}>
      {({ match }) => (
        <CSSTransition
          in={match != null}
          timeout={300}
          classNames="page"
          unmountOnExit
        >
          <div className="page">
            <Component />
            {console.log(match != null)}
          </div>
        </CSSTransition>
      )}
    </Route>
  ));

  routeComponents.push(
    <Route>
      {routeProps => {
        console.log(routeProps);
        if ( routes.filter(r => r.path === routeProps.location.pathname).length === 0 ) {
          return (
            <CSSTransition
              in={routeProps.match != null}
              timeout={300}
              classNames="fade"
              unmountOnExit
            >
              <InvalidPage />
            </CSSTransition>
          );
        } else {
          return <div></div>;
        }
      }}
    </Route>
  );

  return routeComponents;
}

export default SiteRoutes;