React Dom 路由未按预期工作,更改了路径但页面上没有任何内容
React Dom Routes not working as intended, changes the path but nothing on the page
我正在制作一个使用 OpenLibrary API 的网络平台,我正在从主题中提取数据,然后当您单击主题中的一本书时,我想转到一个名为 [= =24=] 我显示数据的地方。
现在我已经设置了我的路线(我认为它们是正确的),但是当我点击列表中的一个项目时,它没有做任何事情,它将 URL 更改为我设置的路线,但它不会将我带到显示数据的 Book 组件。现在,我还没有发布我的 Book.js 文件,因为它只有测试代码来查看我是否可以访问该组件。任何帮助将不胜感激!
以下是我的一些代码片段:
App.js:
import React, { useState, useEffect } from "react";
import axios from "axios";
import Works from "./components/Works";
import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
import "./styles.css";
function App() {
const [subjects, setSubjects] = useState([]);
const [worksDetails, setWorkDetails] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const url = "https://openlibrary.org/subjects/animals.json?limit=10";
useEffect(() => {
axios
.get(url)
.then((response) => {
setSubjects(response.data);
setWorkDetails(response.data.works);
setIsLoading(true);
})
.catch((error) => {
console.log(error);
});
}, []);
if (!isLoading) {
return <p>Loading...</p>;
} else {
return (
<>
<Navbar />
<div className="contentHeader">
<h1 className="subjectHeader" style={{ padding: "10px" }}>
Subject: {subjects.name.toUpperCase()}
</h1>
<h1 className="workHeader" style={{ padding: "10px" }}>
Work Count: {subjects.work_count.toLocaleString()}
</h1>
</div>
<div>
<Works works={worksDetails} />
</div>
<Footer />
</>
);
}
}
export default App;
Works.js
import React from "react";
import { Link } from "react-router-dom";
import Book from "../routes/Book";
const Works = (props) => {
return (
<div className="container">
<div>
<div className="heading">
{props.works.map((work) => {
return (
<Link to={`/book/${work.key}`} element={<Book />} key={work.key}>
<ul>{work.title}</ul>
</Link>
);
})}
</div>
</div>
</div>
);
};
export default Works;
Index.js
import { createRoot } from "react-dom/client";
import "./index.css";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./App";
import Book from "./routes/Book";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<BrowserRouter>
<Routes>
<Route path="*" element={<App />} />
<Route path="/book" element={<Book />}>
<Route path=":bookId" element={<Book />} />
</Route>
</Routes>
</BrowserRouter>
);
我相信你的路线应该是这样的:
<Route path="/book/:bookId" element={<Book />}>
问题
当你使用
<Route path="/book" element={<Book />}>
<Route path=":bookId" element={<Book />} />
</Route>
Route
组件期望 Book
为嵌套的 Route
组件呈现 Outlet
组件。这似乎不是您想要的用户体验。外部路由被匹配和渲染,但是由于没有出口,内部路由渲染 actual Book
组件你想要的参数根本没有渲染。
事实证明,在获取的数据中 work.key
不仅是一个 id,而且似乎是一个嵌套的路由值,即类似于 "key": "/works/OL138052W"
,因此 UI正在计算格式错误的路由 ("/book//works/OL138052W"
) and 链接到一条不存在的路由不存在。
解决方案
to={`/book${work.key}`}
是您链接到的路径,请注意删除“book”和注入的 work.key
值之间的 "/"
:
<Link key={work.key} to={`/book${work.key}`}>
<ul>{work.title}</ul>
</Link>
然后应该呈现以下之一:
<Route path="/book/works/:bookId" element={<Book />} />
或
<Route path="/book/works">
<Route path=":bookId" element={<Book />} /> // "/book/works/:bookId"
</Route>
如果您不想弄乱这个 work.key
值,那么您可能想要 select 其他属性之一,只要它们提供足够的唯一性以供识别。
我正在制作一个使用 OpenLibrary API 的网络平台,我正在从主题中提取数据,然后当您单击主题中的一本书时,我想转到一个名为 [= =24=] 我显示数据的地方。 现在我已经设置了我的路线(我认为它们是正确的),但是当我点击列表中的一个项目时,它没有做任何事情,它将 URL 更改为我设置的路线,但它不会将我带到显示数据的 Book 组件。现在,我还没有发布我的 Book.js 文件,因为它只有测试代码来查看我是否可以访问该组件。任何帮助将不胜感激!
以下是我的一些代码片段:
App.js:
import React, { useState, useEffect } from "react";
import axios from "axios";
import Works from "./components/Works";
import Navbar from "./components/Navbar";
import Footer from "./components/Footer";
import "./styles.css";
function App() {
const [subjects, setSubjects] = useState([]);
const [worksDetails, setWorkDetails] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const url = "https://openlibrary.org/subjects/animals.json?limit=10";
useEffect(() => {
axios
.get(url)
.then((response) => {
setSubjects(response.data);
setWorkDetails(response.data.works);
setIsLoading(true);
})
.catch((error) => {
console.log(error);
});
}, []);
if (!isLoading) {
return <p>Loading...</p>;
} else {
return (
<>
<Navbar />
<div className="contentHeader">
<h1 className="subjectHeader" style={{ padding: "10px" }}>
Subject: {subjects.name.toUpperCase()}
</h1>
<h1 className="workHeader" style={{ padding: "10px" }}>
Work Count: {subjects.work_count.toLocaleString()}
</h1>
</div>
<div>
<Works works={worksDetails} />
</div>
<Footer />
</>
);
}
}
export default App;
Works.js
import React from "react";
import { Link } from "react-router-dom";
import Book from "../routes/Book";
const Works = (props) => {
return (
<div className="container">
<div>
<div className="heading">
{props.works.map((work) => {
return (
<Link to={`/book/${work.key}`} element={<Book />} key={work.key}>
<ul>{work.title}</ul>
</Link>
);
})}
</div>
</div>
</div>
);
};
export default Works;
Index.js
import { createRoot } from "react-dom/client";
import "./index.css";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./App";
import Book from "./routes/Book";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<BrowserRouter>
<Routes>
<Route path="*" element={<App />} />
<Route path="/book" element={<Book />}>
<Route path=":bookId" element={<Book />} />
</Route>
</Routes>
</BrowserRouter>
);
我相信你的路线应该是这样的:
<Route path="/book/:bookId" element={<Book />}>
问题
当你使用
<Route path="/book" element={<Book />}>
<Route path=":bookId" element={<Book />} />
</Route>
Route
组件期望 Book
为嵌套的 Route
组件呈现 Outlet
组件。这似乎不是您想要的用户体验。外部路由被匹配和渲染,但是由于没有出口,内部路由渲染 actual Book
组件你想要的参数根本没有渲染。
事实证明,在获取的数据中 work.key
不仅是一个 id,而且似乎是一个嵌套的路由值,即类似于 "key": "/works/OL138052W"
,因此 UI正在计算格式错误的路由 ("/book//works/OL138052W"
) and 链接到一条不存在的路由不存在。
解决方案
to={`/book${work.key}`}
是您链接到的路径,请注意删除“book”和注入的 work.key
值之间的 "/"
:
<Link key={work.key} to={`/book${work.key}`}>
<ul>{work.title}</ul>
</Link>
然后应该呈现以下之一:
<Route path="/book/works/:bookId" element={<Book />} />
或
<Route path="/book/works">
<Route path=":bookId" element={<Book />} /> // "/book/works/:bookId"
</Route>
如果您不想弄乱这个 work.key
值,那么您可能想要 select 其他属性之一,只要它们提供足够的唯一性以供识别。