Я пытался обновить 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-скрипты!!