#javascript #reactjs #typescript #react-router-dom
#javascript #reactjs #typescript #react-router-dom
Вопрос:
Я начинаю работу над проектом React, использующим react-router-dom, и клиенту необходимо преобразовать код проекта в 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 amp;amp; isPrivate) {
return <Redirect exact to="/signin" />;
}
if (signed amp;amp; !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. Typescript — это надмножество JavaScript. Итак, это уже typescript. С какой проблемой вы столкнулись?
2. В первой строке файла 6 и 7 «Элемент привязки’Component’ неявно имеет тип ‘any’.» и «Элемент привязки’isPrivate’ неявно имеет тип’any'».
3. Вы собираетесь спросить нас, как добавлять типы для каждой строки этого кода?
4. Да, пожалуйста, извините, я запутался в проблеме
5. Это слишком широко для stackoverflow (мы могли бы написать об этом серию блогов)
Ответ №1:
Я считаю, что проблема в основном в RouteWrapper
. Во-первых, давайте предположим, что вы больше не захотите использовать prop-типы, поскольку типы теперь проверяются TypeScript во время компиляции.
Это основы:
- React экспортируется с помощью
module.exports = React
. Это означает, что технически правильный способ импортировать React — этоimport * as React from 'react';
. В качестве альтернативы вы можете установить"esModuleInterop": true
tsconfig.json
. - Возвращаемый тип компонентов React —
React.ReactElement
.
Также можно использовать деструктурирование для назначения простых реквизитов по умолчанию в функциональных компонентах.
For <RouteWrapper />
specifically component
извлекается из реквизита, а затем передается <Route />
вместе с другими реквизитами. Это означает, что он также может быть включен в rest props.
Поскольку остальные реквизиты передаются в <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 amp;amp; isPrivate) {
return <Redirect exact to="/signin" />;
}
if (signed amp;amp; !isPrivate) {
return <Redirect to="/" />;
}
return <Route {...rest} />;
}
Если вы действительно хотите использовать propTypes
или defaultProps
, безопасность типов можно добавить с помощью 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 amp;amp; isPrivate) {
return <Redirect exact to="/signin" />;
}
if (signed amp;amp; !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>
);
}
Это должно помочь вам начать преобразование остальной части приложения. 🙂
Комментарии:
1. Сначала я хочу поблагодарить вас за ваш ответ, я пытаюсь с помощью вашего кода поместить, что я нашел эту проблему «Type ‘{ isPrivate: PropTypes. Требуемое значение <логическое значение>; }’ не может быть присвоено типу ‘WeakValidationMap<RouteWrapperProps>’.»