如何将React Router函数转换为Typescript?

时间:2020-10-16 13:16:13

标签: javascript reactjs typescript react-router-dom

我开始使用React-router-dom在React Project上工作,客户端需要将项目代码转换为Typescript

我建立2个文件夹“ RouteWrapper.js”和“ ProviderRoutes.js”

1-“ RouteWrapper.js”

import React from 'react';
import PropTypes from 'prop-types';
import { Route, Redirect } from 'react-router-dom';

export default function RouteWrapper({
  component: Component,
  isPrivate,
  ...rest
}) {
  const signed = false;

  if (!signed && isPrivate) {
    return <Redirect exact to="/signin" />;
  }

  if (signed && !isPrivate) {
    return <Redirect to="/" />;
  }

  return (
    <Route {...rest} component={Component} />
  );
}

RouteWrapper.propTypes = {
  isPrivate: PropTypes.bool,
  component: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
    .isRequired,
};

RouteWrapper.defaultProps = {
  isPrivate: false,
};

2-“ ProviderRoutes.js”

import React from 'react';
import { Switch } from 'react-router-dom';

// Components
import Route from './RouteWrapper';
import Authentication from '../Layouts/Authentication/Authentication.Layout';
import ChatApplication from '../Layouts/ChatApplication/ChatApplication.Layout';

export default function ProviderRoutes() {
  return (
    <Switch>
        <Route exact path={["/signin", "/signup", "/reset-password"]} component={Authentication} />
        <Route path="/" component={ChatApplication} isPrivate />
    </Switch>
  )
}

1 个答案:

答案 0 :(得分:1)

我认为问题主要出在RouteWrapper。首先,假设您不再想要使用 道具类型,因为现在可以在TypeScript编译时检查类型。

这些是基础知识:

  • 使用module.exports = React导出反应。这意味着技术上正确的导入方式 React是import * as React from 'react';。或者,您可以在"esModuleInterop": true中设置 tsconfig.json
  • React组件的返回类型为React.ReactElement

还可以使用分解功能在功能组件中分配简单的默认道具。

对于<RouteWrapper />,特别是component从道具中提取,然后传递给 <Route />以及其他道具。这意味着它也可能会包含在其余道具中。

由于其余道具传递到<Route />,因此<RouteWrapper />的道具类型应 从RouteProps扩展react-router-dom

RouteWrapper看起来像这样:

import * as React from 'react';
import { Redirect, Route, RouteProps } from 'react-router-dom';

interface RouteWrapperProps extends RouteProps {
  isPrivate: boolean;
}

export default function RouteWrapper({
  isPrivate = false,
  ...rest
}: RouteWrapperProps): ReactElement {
  const signed = false;

  if (!signed && isPrivate) {
    return <Redirect exact to="/signin" />;
  }

  if (signed && !isPrivate) {
    return <Redirect to="/" />;
  }

  return <Route {...rest} />;
}

如果您确实要使用propTypesdefaultProps,则可以使用React.FC添加安全类型。

import * as PropTypes from 'prop-types';
import * as React from 'react';
import { Redirect, Route, RouteProps } from 'react-router-dom';

interface RouteWrapperProps extends RouteProps {
  isPrivate: boolean;
}

const RouteWrapper: React.FC<RouteWrapperProps> = ({ isPrivate, ...rest }) => {
  const signed = false;

  if (!signed && isPrivate) {
    return <Redirect exact to="/signin" />;
  }

  if (signed && !isPrivate) {
    return <Redirect to="/" />;
  }

  return <Route {...rest} />;
};

RouteWrapper.propTypes = {
  isPrivate: PropTypes.bool,
};

RouteWrapper.defaultProps = {
  isPrivate: false,
};

export default RouteWrapper;

请注意,使用react-router编写路由的首选方式是使用子级,而不是 component道具。

import * as React from 'react';
import { Switch } from 'react-router-dom';

// Components
import RouteWrapper from './RouteWrapper';
import Authentication from '../Layouts/Authentication/Authentication.Layout';
import ChatApplication from '../Layouts/ChatApplication/ChatApplication.Layout';

export default function ProviderRoutes(): React.ReactElement {
  return (
    <Switch>
      <Route exact path={['/signin', '/signup', '/reset-password']}>
        <Authentication />
      </Route>
      <Route isPrivate path="/">
        <ChatApplication />
      </Route>
    </Switch>
  );
}

这应该可以帮助您开始转换其余的应用程序。 :)