代码在最新的React Router中不起作用吗?

huangapple go评论74阅读模式
英文:

code not working in latest react-router-dom in react router?

问题

在React中,我想运行一个与应用程序相关的React Router;这是没问题的;问题在于特定的代码,例如"react-router-dom":"6.8.1"在最新的React版本中不运行并引发错误。

"元素类型无效:预期为字符串(用于内置组件)或类/函数(用于组合组件),但得到了undefined。你可能忘记从文件中导出组件,或者可能混淆了默认导入和命名导入。"

但如果你更改版本,比如"react-router-dom":"5.2.1",这段代码就能正常工作。因此,我的问题是在"react-router-dom":"6.8.1"中如何成功运行这段代码?在我的App.js中的代码结构中,我应该改变什么东西才能使这段代码在6.8.1中也能完美运行?

import { useState } from "react";
import {
  BrowserRouter as Router,
  generatePath,
  Switch,
  Route,
  useHistory,
  useParams
} from "react-router-dom";

const products = [
  {
    id: "1",
    name: "Product 1"
  },
  {
    id: "2",
    name: "Product 2"
  },
  {
    id: "3",
    name: "Product 3"
  }
];

const Products = () => {
  const { id } = useParams();

  console.log(id);
  return (
    <div>
      <p>Lorem Ipsum</p>
      <p>Id: {id}</p>
    </div>
  );
};

const Home = () => {
  const [id, setId] = useState();
  const history = useHistory();
  console.log(history)
  const handleProceed = (e) => {
    id && history.push(generatePath("/products/:id", { id }));
  };

  return (
    <div
      style={{ display: "flex", flexDirection: "column", alignItems: "center" }}
    >
      <div>
        {products.map((product, i) => (
          <button
            key={i}
            onClick={(e) => {
              setId(product.id);
            }}
          >
            {product.name}
          </button>
        ))}
      </div>
      <button onClick={handleProceed} style={{ width: "250px" }}>
        Click
      </button>
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <header>Heading</header>
      <Router>
        <Switch>
          <Route path="/products/:id">
            <Products />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </Router>
    </div>
  );
}
英文:

in react I want to run an application-related react-router; that is fine; the problem is that specific code, such as "react-router-dom": "6.8.1," does not run in the latest react version and throws an error.

> "Element type is invalid: expected a string (for built-in components)
> or a class/function (for composite components) but got: undefined. You
> likely forgot to export your component from the file it's defined in,
> or you might have mixed up default and named imports."

But if you change the version, it's working fine, like in "react-router-dom": "5.2.1", This code is working fine, ,so my question is in "react-router-dom": :6.8.1 How to successfully run that code?in my App.js in code structure which thing should I have to change that code will run perfectly in 6.8.1 too?

import { useState } from &quot;react&quot;;
import {
BrowserRouter as Router,
generatePath,
Switch,
Route,
useHistory,
useParams
} from &quot;react-router-dom&quot;;
const products = [
{
id: &quot;1&quot;,
name: &quot;Product 1&quot;
},
{
id: &quot;2&quot;,
name: &quot;Product 2&quot;
},
{
id: &quot;3&quot;,
name: &quot;Product 3&quot;
}
];
const Products = () =&gt; {
const { id } = useParams();
console.log(id);
return (
&lt;div&gt;
&lt;p&gt;Lorem Ipsum&lt;/p&gt;
&lt;p&gt;Id: {id}&lt;/p&gt;
&lt;/div&gt;
);
};
const Home = () =&gt; {
const [id, setId] = useState();
const history = useHistory();
console.log(history)
const handleProceed = (e) =&gt; {
id &amp;&amp; history.push(generatePath(&quot;/products/:id&quot;, { id }));
};
return (
&lt;div
style={{ display: &quot;flex&quot;, flexDirection: &quot;column&quot;, alignItems: &quot;center&quot; }}
&gt;
&lt;div&gt;
{products.map((product, i) =&gt; (
&lt;button
key={i}
onClick={(e) =&gt; {
setId(product.id);
}}
&gt;
{product.name}
&lt;/button&gt;
))}
&lt;/div&gt;
&lt;button onClick={handleProceed} style={{ width: &quot;250px&quot; }}&gt;
Click
&lt;/button&gt;
&lt;/div&gt;
);
};
export default function App() {
return (
&lt;div className=&quot;App&quot;&gt;
&lt;header&gt;Heading&lt;/header&gt;
&lt;Router&gt;
&lt;Switch&gt;
&lt;Route path=&quot;/products/:id&quot;&gt;
&lt;Products /&gt;
&lt;/Route&gt;
&lt;Route path=&quot;/&quot;&gt;
&lt;Home /&gt;
&lt;/Route&gt;
&lt;/Switch&gt;
&lt;/Router&gt;
&lt;/div&gt;
);
}

答案1

得分: 1

react-router@6 带来了大量的破坏性变化。您应该查看从 v5 升级迁移指南以获取完整的详细信息。

Switch 组件被 Routes 组件替代,该组件需要直接包装您正在渲染的 Route,而 useHistory 钩子被 useNavigate 钩子替代。

import { useState } from "react";
import {
  BrowserRouter as Router,
  generatePath,
  Routes,
  Route,
  useNavigate,
  useParams
} from "react-router-dom";

useNavigate 返回一个 navigate 函数,而不是一个 "history" 对象。调用 navigate 发出命令式导航操作。

const Home = () => {
  const [id, setId] = useState();
  const navigate = useNavigate();

  const handleProceed = () => {
    navigate(generatePath("/products/:id", { id }));
  };

  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        alignItems: "center"
      }}
    >
      <div>
        {products.map((product) => (
          <button
            key={product.id}
            type="button"
            onClick={() => {
              setId(product.id);
            }}
          >
            {product.name}
          </button>
        ))}
      </div>
      <button
        type="button"
        disabled={!id}
        onClick={handleProceed}
        style={{ width: "250px" }}
      >
        Click
      </button>
    </div>
  );
};

Route 组件的 API/props 发生了变化,所有路由内容都呈现在 Route 组件的 element 属性上。

export default function App() {
  return (
    <div className="App">
      <header>Heading</header>
      <Router>
        <Routes>
          <Route path="/products/:id" element={<Products />} />
          <Route path="/" element={<Home />} />
        </Routes>
      </Router>
    </div>
  );
}
英文:

react-router@6 brought with it a ton of breaking changes. You should review the Upgrading from v5 migration guide for the full details.

The Switch component was replaced by the Routes component which is required to directly wrap Routes you are rendering, and the useHistory hook was replaced by the useNavigate hook.

import { useState } from &quot;react&quot;;
import {
  BrowserRouter as Router,
  generatePath,
  Routes,
  Route,
  useNavigate,
  useParams
} from &quot;react-router-dom&quot;;

useNavigate returns a navigate function instead of a "history" object. Call navigate to issue imperative navigation actions.

const Home = () =&gt; {
  const [id, setId] = useState();
  const navigate = useNavigate();

  const handleProceed = () =&gt; {
    navigate(generatePath(&quot;/products/:id&quot;, { id }));
  };

  return (
    &lt;div
      style={{
        display: &quot;flex&quot;,
        flexDirection: &quot;column&quot;,
        alignItems: &quot;center&quot;
      }}
    &gt;
      &lt;div&gt;
        {products.map((product) =&gt; (
          &lt;button
            key={product.id}
            type=&quot;button&quot;
            onClick={() =&gt; {
              setId(product.id);
            }}
          &gt;
            {product.name}
          &lt;/button&gt;
        ))}
      &lt;/div&gt;
      &lt;button
        type=&quot;button&quot;
        disabled={!id}
        onClick={handleProceed}
        style={{ width: &quot;250px&quot; }}
      &gt;
        Click
      &lt;/button&gt;
    &lt;/div&gt;
  );
};

The Route component API/props changed, all the routed content is rendered on the Route component's element prop.

export default function App() {
  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;header&gt;Heading&lt;/header&gt;
      &lt;Router&gt;
        &lt;Routes&gt;
          &lt;Route path=&quot;/products/:id&quot; element={&lt;Products /&gt;} /&gt;
          &lt;Route path=&quot;/&quot; element={&lt;Home /&gt;} /&gt;
        &lt;/Routes&gt;
      &lt;/Router&gt;
    &lt;/div&gt;
  );
}

答案2

得分: 0

对于React Router v6,应该使用useNavigate而不是useHistoryuseHistory不再存在)。

const navigate = useNavigate();
// ...
id && navigate(generatePath("/products/:id", { id }));
英文:

For React Router v6, useNavigate should be used instead of useHistory (which no longer exists).

const navigate = useNavigate();
// ...
id &amp;&amp; navigate(generatePath(&quot;/products/:id&quot;, { id }));

huangapple
  • 本文由 发表于 2023年2月19日 11:42:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75497851.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定