簡體   English   中英

當我嘗試將 react-router v5 升級到 V6 時出現錯誤

[英]Getting error when I try to upgrade react-router v5 to V6

當我嘗試將 React-router-dom v5 升級到 v6 時出現 typescript 錯誤,我該如何修復這個 typescript 錯誤。 您可以在下面找到代碼提前致謝

`

export function withRouter(ui: React.ReactElement) {
  const history = useNavigate();
  const routerValues: any = {
    history: undefined,
    location: undefined
  };

  const result = (
    <MemoryRouter>
      {ui}
      <Route
        path="*"
        element={({ history, location }) => {
          routerValues.history = history;
          routerValues.location = location;
          return null;
        }}
      />
    </MemoryRouter>

在此處輸入圖像描述`

下面你可以找到整個文件代碼`

import React from "react";
import { Reducer } from "@reduxjs/toolkit";
import { Provider } from "react-redux";
import { MemoryRouter, Route, useNavigate } from "react-router-dom";
import buildStore from "../redux/store";

export function withRedux(
  ui: React.ReactElement,
  reducer: {
    [key: string]: Reducer;
  },
  initialState: any
) {
  const store = buildStore(initialState, true);
  const dispatchSpy = jest.spyOn(store, "dispatch");

  return {
    result: <Provider store={store}>{ui}</Provider>,
    store,
    dispatchSpy
  };
}

export function withRouter(ui: React.ReactElement) {
  const history = useNavigate();
  const routerValues: any = {
    history: undefined,
    location: undefined
  };

  const result = (
    <MemoryRouter>
      {ui}
      <Route
        path="*"
        element={({ history, location }) => {
          routerValues.history = history;
          routerValues.location = location;
          return null;
        }}
      />
    </MemoryRouter>
  );

  return { result, routerValues };
}

`

我正在傳遞歷史和位置道具,當我使用 react router v5 時這些道具工作正常這里是以前的代碼:`

const result = (
    <MemoryRouter>
      {ui}
      <Route
        path="*"
        render={({ history, location }) => {
          routerValues.history = history;
          routerValues.location = location;
          return null;
        }}
      />
    </MemoryRouter>

`

更新 react router v6 后,我更改了代碼,因為我們知道 v6 不再支持路由內的 render 關鍵字,所以我將其替換

`

const result = (
    <MemoryRouter>
      {ui}
      <Route
        path="*"
        element={({ history, location }) => {
          routerValues.history = history;
          routerValues.location = location;
          return null;
        }}
      />
    </MemoryRouter>
  );

`

但是我在 v6 中沒有 Idea 如何在路由中傳遞這些道具

試試這個:

export function withRouter(ui: React.ReactElement) {
  const history = useNavigate();
  const location = useLocation();
  
  const routerValues: any = {
    history: history,
    location: location
  };

  const result = (
    <MemoryRouter>
      {ui}
    </MemoryRouter>
  );

  return { result, routerValues };
}

問題

  1. withRouter Higher Order Component/render function不能在它正在渲染的路由器之外使用 RRD 掛鈎。
  2. react-router-dom@6 Route組件不采用“路由道具”, element道具采用React.ReactNode ,又名 JSX。 “路由道具”應該作為道具傳遞給正在渲染的組件。

解決方案

您需要創建兩個組件。 一個是測試渲染 function,它提供MemoryRouter作為測試包裝器,另一個是正確的withRouter HOC。

示例:創建自定義渲染 function,將被測組件渲染到提供所有各種上下文(路由器、redux 等)的包裝器組件中

import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';

const Wrappers = ({ children }) => (
  <MemoryRouter>
    {children}
  </MemoryRouter>
);

const customRender = (ui: React.ReactElement, options: object) => {
  return render(ui, { wrapper: Wrappers, ...options });
};

export { customRender as render };

有關自定義渲染函數的更多信息,請參閱 RTL 設置文檔。

創建單獨withRouter HOC 以僅裝飾不能直接使用 RRD 掛鈎的舊 React Class 組件。 這是一個示例 Typescript 實現。

import { ComponentType } from 'react';
import {
  Location,
  NavigateFunction,
  useLocation,
  useParams
} from 'react-router-dom';

export interface WithRouterProps {
  location: Location;
  navigate: NavigateFunction;
  params: ReturnType<typeof useParams>;
}

export const withRouter = <P extends object>(Component: ComponentType<P>) => 
  (props: Omit<P, keyof WithRouterProps>) => {
    const location = useLocation();
    const params = useParams();
    const navigate = useNavigate();

    return (
      <Component
        {...props}
        {...{ location, params, navigate }}
      />
    );
  };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM