在react中我想运行一个应用相关的react-router;没事儿;问题是特定代码,例如“react-router-dom”:“6.8.1”,不能在最新的 React 版本中运行并抛出错误。
“元素类型无效:需要一个字符串(对于内置组件) 或类/函数(对于复合组件)但得到:未定义。你 可能忘记从定义它的文件中导出您的组件, 或者您可能混淆了默认导入和命名导入。”
但是如果你改变版本,它工作正常,比如在“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>
);
}
对于 React Router v6,应该使用 useNavigate
代替 useHistory
(不再存在)。
const navigate = useNavigate();
// ...
id && navigate(generatePath("/products/:id", { id }));
看起来问题出在 generatePath
的导入语句上,
useHistory
,以及 useParams
版本 6 中的 react-router-dom
。这些导入的语法已从版本 5 更改为版本 6,因此您需要更新导入语句。
这里更新你的代码:
import { useState } from "react";
import {
BrowserRouter as Router,
Switch,
Route,
useNavigate,
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 navigate = useNavigate();
console.log(navigate)
const handleProceed = (e) => {
id && navigate(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>
);
}