对于不同的路线,不会安装相同的反应组件

For different route, same react component does not get mounted

我在为两条不同的路线使用相同的组件时遇到问题,我希望该组件被破坏然后再次安装,但这并没有发生:

当我通过单击按钮 Change to /page2/page1 更改为 /page2 时,控制台中的输出应该是:

COMPONENT DISMOUNTED
COMPONENT MOUNTED

这意味着MyComponent应该在路径改变后销毁。这很重要,因为我依赖这样一个事实,即路径的改变会给我新鲜的成分。我不想手动将状态和其他挂钩重置为默认值。
Codesadnbox example

是否存在 React 问题或 React 路由器问题?

应用组件

import {
  Routes,
  Route,
  BrowserRouter,
  Navigate
} from 'react-router-dom';

const App = () => {
  return (
    <BrowserRouter>
      {/* Routes */}
      <Routes>
        {/* Route 1 */}
        <Route path="/page1" element={<MyComponent someProp="value1" />} />
        {/* Route 2 */}
        <Route path="/page2" element={<MyComponent someProp="value2" />} />

        <Route path="/*" element={<Navigate to={{ pathname: '/page1' }} />} />
      </Routes>
    </BrowserRouter>
  );
};

我的组件

import type { FunctionComponent } from 'react';
import { useEffect } from 'react';

import {
  useNavigate
} from 'react-router-dom';

const MyComponent: FunctionComponent<{ someProp: string }> = ({ someProp }) => {
  const history = useNavigate();

  const onRouteChange = (route: string) => {
    history(route);
  };

  useEffect(() => {
    console.log('COMPONENT MOUNTED');

    return () => {
      console.log('COMPONENT DISMOUNTED');
    };
  }, []);

  return (
    <div>
      <button onClick={() => onRouteChange('/page1')}>Change to /page1</button>
      <button onClick={() => onRouteChange('/page2')}>Change to /page2</button>

      <div>{someProp}</div>
    </div>
  );
};

React 实际上正确地完成了它的工作,因为 Route 组件 returns 相同的组件更改了 prop someProp。在任何其他情况下,如果我有一个组件我更改了它的属性,这会再次发生。

除非您偶然发现这个问题,否则没有明显的方法可以找出这个问题。虽然以 React 的工作方式思考,但这应该是显而易见的。

解决方案
应将简单 key 添加到两个 MyComponent 组件中。这样,React 就会知道,由于 key 不同,Route 返回的新组件也不同。
Codesandbox to the solution

const App = () => {
  return (
    <BrowserRouter>
      {/* Routes */}
      <Routes>
        {/* Route 1 */}
        <Route
          path="/page1"
          element={<MyComponent key="/page1" someProp="value1" />}
        />
        {/* Route 2 */}
        <Route
          path="/page2"
          element={<MyComponent key="/page2" someProp="value2" />}
        />

        <Route path="/*" element={<Navigate to={{ pathname: "/page1" }} />} />
      </Routes>
    </BrowserRouter>
  );
};