Я пытался обновить React Router с v5 до v6, поэтому я просмотрел и подытожил то, что сделал. Мы стараемся обновлять код с минимальными исправлениями, чтобы его было легче просматривать.

Пожалуйста, сначала ознакомьтесь с процедурой обновления на официальном сайте.

То, что я работал сегодня, выглядит следующим образом.

Поддерживает изменение типа useParams
Поддерживает изменение типа ‹NavLink /›
Изменяет ‹Switch /› на ‹Routes /›
Поддерживает изменение типа ‹Route /›
Изменить ‹ Перенаправить /› на ‹Navigate /›
Изменить useHistory на useNavigate
Изменить useRouteMatch на useMatch

Давайте начнем.

Поддерживает изменение типа useParams

При получении параметра пути, такого как /user/:userId/content/:contentId, сама v5 выглядит следующим образом:

type ParhParams = {
 userId: string;
 contentId: string;
};
const { userId, contentId } = useParams<Params>();

v6 теперь определяется следующим образом

export declare function useParams<Key extends string = string>(): Readonly<
 Params<Key>
>;
export declare type Params<Key extends string = string> = {
 readonly [key in Key]: string | undefined;
};
// type of userId and contentId is `string | undefined` 
const { userId, contentId } = useParams<”userId” | “contentId”>();

Следовательно, необходимо иметь дело со случаем undefined. Можно сделать что-то вроде userId ?? “”, но я использовал функции утверждения, чтобы справиться с этим.

function assertIsDefined<T>(val: T): asserts val is NonNullable<T> {
 if (val === undefined || val === null) {
 throw new AssertionError(
 `Expected ‘val’ to be defined, but received ${val}`
 );
 }
}

Поддерживает изменение типа ‹NavLink /›

Требуется простое переименование с точного реквизита на конец.

Прекращение поддержки ActiveClassName и activeStyle, вероятно, потребует серьезных изменений в некоторых случаях. Заменяемый проект использует Material UI v5 и не может быть описан следующим образом:

импортировать {Link} из @mui/material»;
импортировать {NavLink} из react-router-dom;

<Link
 className={({ isActive }) => (isActive ? “isActive” : “”)}
 component={NavLink}
 to=”/”
>
 {children}
</Link>;

Проблемных моментов было всего несколько, с ними я справляюсь следующим образом.

<Box sx={{ “> .isActive”: { color: “white” } }}>
 <NavLink className={({ isActive }) => (isActive ? “isActive” : “”)} {…rest}>
 {children}
 </NavLink>
</Box>

Кажется, хорошо иметь обертку, как объяснено официально.

Измените ‹Switch /› на ‹Routes /›.

Это была простая замена, потому что обновляемый проект не вкладывал Switch.

Поддерживает изменение типа ‹Route /›

Удалил точно так как он больше не нужен.

Преобразование компонента в элемент было простой задачей, но если вы используете Auth0 для аутентификации, как показано ниже

const ProtectedRoute = (props: RouteProps) => {
 const { component, …rest } = props;
return (
 <Route
 component={withAuthenticationRequired(component as React.ComponentType)}
 {…rest}
 />
 );
};

Поскольку element = {withAuthenticationRequired (component)} не может быть установлен, необходимо принять следующие меры:

const Protected = withAuthenticationRequired (Outlet);

Измените ‹Перенаправление /› на ‹Навигация /›.

В v5 для push требуется спецификация реквизита, но в v6 по умолчанию используется push, а для замены требуется спецификация replace.

// v5
<Redirect to=”/foo” />
<Redirect to=”/bar” push />
// v6
<Navigate to=”/foo” replace />
<Navigate to=”/bar” />

Измените useHistory на useNavigate.

// v5
const history = useHistory();
history.push(“/”);
history.replace(“/”);
history.goBack();
// v6
const navigate = useNavigate();
navigate(“/”);
navigate(“/”, { replace: true });
navigate(-1);

Как и в случае с ‹Navigate /›, если по умолчанию используется push или replace, вам необходимо указать это. В случае go, goBack, goForward укажите номер в качестве аргумента.

Измените useRouteMatch на useMatch

От v5 до v6 изменился способ получения Path Pattern текущего URL (например, /user/:userId) со стороны компонента.

В v5 вы могли просто использовать useRouteMatch, но useMatch необходимо передать шаблон пути, который вы хотите проверить, чтобы получить шаблон пути.

// v5
const match = useRouteMatch ();
// v6
const match = useMatch (“/user /:userId”);

Поэтому вы не можете использовать useMatch, если условие имеет несколько шаблонов пути.

Например, если вы хотите что-то сделать с URL-адресом /foo или /bar, вы должны использовать matchPath вместо useMatch.

const { pathname } = useLocation();
const match = useMemo(() => {
 return [“/foo”, “/bar”].find((path) => !!matchPath(path, pathname));
}, [pathname]);

Краткое содержание

Я думаю, что было бы более удобно для обозревателей сосредоточиться на минимальных исправлениях кода для PR обновлений пакетов, разработанных командой, и эта статья также сосредоточилась на этом.

Java-скрипты!!