当前位置: 首页 > 知识库问答 >
问题:

使用打字稿和反应在私有路线中传递组件道具

隗轶
2023-03-14

我正在使用React路由器v4中的路由组件的渲染道具来实现具有Typecript和React的认证路由。

路线:

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import { ROUTES } from 'utils/constants';
import HomePage from 'components/pages/Home';
import GuestLogin from 'components/pages/GuestLogin';
import ProfilePage from 'components/pages/Profile';
import NotFoundPage from 'components/pages/NotFound';
import ResetPassword from 'components/pages/ResetPassword';
import SetPassword from 'components/pages/SetPassword';
import LoginContainer from 'containers/Login';
import PrivateRoute from './PrivateRoute';

const Routes: React.FunctionComponent = () => (
  <Switch>
    <Route path={ROUTES.LOGIN} component={LoginContainer} exact></Route>
    <PrivateRoute
      path={ROUTES.HOME}
      component={HomePage}
    ></PrivateRoute>
    <Route path={ROUTES.GUEST_LOGIN} component={GuestLogin}></Route>
    <Route path={ROUTES.RESET_PASSWORD} component={ResetPassword}></Route>
    <Route path={ROUTES.SET_PASSWORD} component={SetPassword}></Route>
    <Route path={ROUTES.PROFILE} component={ProfilePage}></Route>
    <Route component={NotFoundPage}></Route>
  </Switch>
);

export default Routes;

私人路线:

import React from 'react';    
import { useAppContext } from 'containers/App/AppContext';
import { RouteProps, Route, Redirect } from 'react-router-dom';
import { ROUTES } from 'utils/constants';

const PrivateRoute: React.FunctionComponent<RouteProps> = ({
  component: Component,
  ...routeProps
}) => {
  const { isSignedIn } = useAppContext();
  const ComponentToRender = Component as React.ElementType;
  return (
    <Route
      {...routeProps}
      render={(props) =>
        isSignedIn ? (
          <ComponentToRender {...props} />
        ) : (
          <Redirect to={ROUTES.LOGIN} />
        )
      }
    />
  );
};

export default PrivateRoute;

问题是我想调用道具上的组件集,但是,每次我尝试此操作时,Typescript都会抛出以下错误。

JSX element type 'Component' does not have any construct or call signatures.  TS2604

错误的图像

原因似乎是路由的组件类型不是这里所解释的TypeScript期望的组件类型:https://github.com/microsoft/TypeScript/issues/28631,因此我只是创建了一个具有新类型(ComponentToRender)的副本。

有没有更好的方法来实现这一点?可能会覆盖RouteProps组件元素?

谢谢

共有1个答案

薄哲
2023-03-14

我终于明白了错误并解决了它!关键是组件属性和渲染函数的处理方式与类型不同。通过使用RouteProps,Typescript编译器实际上将组件道具设置为ComponentType(根据RouterProps为“component”指定的类型),该类型不能用于渲染函数,如索引中所示。d、 ts文件。

export interface RouteProps {
    location?: H.Location;
    component?: React.ComponentType<RouteComponentProps<any>> | React.ComponentType<any>;
    render?: (props: RouteComponentProps<any>) => React.ReactNode;
    children?: ((props: RouteChildrenProps<any>) => React.ReactNode) | React.ReactNode;
    path?: string | string[];
    exact?: boolean;
    sensitive?: boolean;
    strict?: boolean;
}

只要将渲染函数移动到Routes文件中,而不使用私有路由组件,这种行为就会变得明显。下面的代码按预期工作,因为编译器正确地推断了类型(React.ReactNode)。

<Route
  path={ROUTES.POINTS_HISTORY}
  render={(props) =>
    isSignedIn ? <PointsTransactions /> : <Redirect to={ROUTES.LOGIN} />
  }
></Route>

因此,为了解决这个问题,我只创建了一个新类型,其中只包含用例所需的参数。

import React from 'react';

import { useAppContext } from 'containers/App/AppContext';
import { RouteProps, Route, Redirect } from 'react-router-dom';
import { ROUTES } from 'utils/constants';

type PrivateRouteProps = {
  path: RouteProps['path'];
  component: React.ElementType;
};
const PrivateRoute: React.FunctionComponent<PrivateRouteProps> = ({
  component: Component,
  ...routeProps
}) => {
  const { isSignedIn } = useAppContext();
  return (
    <Route
      {...routeProps}
      render={(props) =>
        isSignedIn ? <Component /> : <Redirect to={ROUTES.LOGIN} />
      }
    />
  );
};

export default PrivateRoute;
 类似资料:
  • 我在克服react路由器的问题时遇到困难。该场景是,我需要从状态父组件和路由向子路由传递一组道具 我想做的是传递its,传递its。然而,我能找到的唯一方法是通过这两个和,这意味着每个子路径都会获得每个子道具,无论其是否相关。目前这不是一个阻塞问题,但我可以看到,有一段时间我会使用同一组件的两个,这意味着propA上的键将被propB上的键覆盖。 这实际上是我所期望的方式。当我链接到我得到组件渲染

  • 我需要通过使用路由器的组件道具。这是我的代码: 如您所见,我验证了我要传递给登录组件的道具。 当我记录道具时,未经验证的道具不存在。我做错了什么?我怎样才能正确地通过道具?我跟踪了文档和其他讨论。据我所知,这应该是可行的。react router和react router dom的版本为4.0.0

  • 我正在尝试为react制作PrivateRoute组件。这是我的高阶组件。你能告诉我这个有什么问题吗。

  • 注意:如果我像其他属性一样添加appState;提交组件中没有appState之类的属性, 如果我用这个; appState传递很好,但这次缺少历史对象,正确的方法是什么?appState只是mobx类实例。 编辑:我找到了一个“奇怪”的解决方案。我将route元素更改为此; 然后,我可以通过访问相同的历史对象在进行此更改之前,我可以将其用作 如果我让它工作正常,但是用这种方式获取这个历史对象很烦

  • 我在一个组件中有一个按钮,单击我想转到另一个组件并将状态传递给该组件。 是这样的: 但它不起作用。单击“我去添加新问题url”,但组件AddNewQuestionPage不会呈现。若我不把路线放在AddQuestions组件中,而是放在应用程序组件中,它就可以工作。它是整个应用程序的主要组件,使用Switch,还设置了其他路由。 但是,如果状态问题是从应用程序组件呈现的,我不知道如何将其传递给Ad