英文:
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 "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>
);
}
答案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 Route
s you are rendering, and the useHistory
hook was replaced by the useNavigate
hook.
import { useState } from "react";
import {
BrowserRouter as Router,
generatePath,
Routes,
Route,
useNavigate,
useParams
} from "react-router-dom";
useNavigate
returns a navigate
function instead of a "history" object. Call navigate
to issue imperative navigation actions.
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>
);
};
The Route
component API/props changed, all the routed content is rendered on the Route
component's element
prop.
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>
);
}
答案2
得分: 0
对于React Router v6,应该使用useNavigate
而不是useHistory
(useHistory
不再存在)。
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 && navigate(generatePath("/products/:id", { id }));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论