英文:
Unable to display data from the List of Films in React
问题
I am working on react-router-dom@6.8
and fetching data using useEffect
hook and updated data with useState
hook.
My routes are in Main
component and nested route of "/films" which have film details is in Films
component. I have attached the screenshot in which I am just able to access the specific id of films but not displaying film detail. Film
is accessed via props in Films
using method findFilms
.
Main.js
import { Routes, Route } from 'react-router-dom'
import { Films } from '../Films/Films'
import { Home } from '../Home/Home'
export const Main = (props) => {
return (
<div className='mainContent'>
<Routes>
<Route path="/films/*" element={<Films />}></Route>
<Route path="/planets/*" element={<Planets />}></Route>
<Route path="/people" element={<People list={people} />}>
<Route path=":id" element={<Person list={people} />}></Route>
</Route>
<Route path="*" element={<Home />}></Route>
</Routes>
</div>
)
}
Films.js
import React from 'react'
import { NavLink, Route, Routes } from 'react-router-dom';
import { Film } from '../Film/Film';
import './films.css';
export const Films = (props) => {
const [list, setList] = useState([]);
useEffect(() => {
(function getFilms() {
let url = 'https://swapi.dev/api/films/';
fetch(url)
.then((resp) => {
if (!resp.ok) throw new Error(resp.statusText);
return resp.json();
})
.then((data) => {
setList(data.results);
})
.catch(console.warn);
})();
}, []);
function findFilm(id) {
return list.find((item, index) => parseInt(id) === index + 1);
}
return (
<>
<div className="results">
<h2>Film List</h2>
{list.length === 0 && <p>No films...</p>}
{list.map((film, index) => (
<p key={film.title}>
<NavLink to={`/films/${index + 1}`} className={({isActive}) => (isActive ? "activeLink" : 'none')}>
{film.title}
</NavLink>
</p>
))}
</div>
<div className="details">
<Routes>
<Route path="/films/:id" element={<Film findFilm={findFilm} />} />
</Routes>
</div>
</>
)
}
Film.js
import { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import React from 'react';
export const Film = ({ findFilm }) => {
const [film, setFilm] = useState(null);
const { id } = useParams();
useEffect(() => {
setFilm(findFilm(id));
}, [findFilm, id]);
let details = (
<>
<p>{film && film.title}</p>
<p>{film && film.release_date}</p>
</>
);
return (
<>
<h2>Film Details</h2>
{film && details}
</>
)
}
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './components/App/App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
Main
component is being rendered in App
component. Please look in the code either I will have to make css file className results to display data or it's a routing problem why code is not able to display data on the planet page, planet is a sub-component of Planet.
英文:
I am working on react-router-dom@6.8
and fetching data using useEffect
hook and updated data with useState
hook.
My routes are in Main
component and nested route of "/films"
which have film details is in Films
component. I have attached the screenshot in which I am just able to access the specific id of films but not displaying film detail. Film
is accessed via props in Films
using method findFilms
.
Main.js
import { Routes, Route } from 'react-router-dom'
import { Films } from '../Films/Films'
import { Home } from '../Home/Home'
export const Main = (props) => {
return (
<div className='mainContent'>
<Routes>
<Route path="/films/*" element={<Films />}></Route>
<Route path="/planets/*" element={<Planets />}></Route>
<Route path="/people" element={<People list={people} />}>
<Route path=":id" element={<Person list={people} />}></Route>
{/* Person is passed prop with fetch results */}
</Route>
<Route path="*" element={<Home />}></Route>
</Routes>
</div>
)
}
Films.js
import React from 'react'
import { NavLink, Route, Routes } from 'react-router-dom';
import { Film } from '../Film/Film'
import './films.css'
export const Films = (props) => {
const [list, setList] = useState([]);
useEffect(() => {
(function getFilms() {
let url = 'https://swapi.dev/api/films/';
fetch(url)
.then((resp) => {
if (!resp.ok) throw new Error(resp.statusText);
return resp.json();
})
.then((data) => {
setList(data.results);
})
.catch(console.warn);
})();
}, []);
function findFilm(id) {
return list.find((item, index) => parseInt(id) === index + 1);
}
return (
<>
<div className="results">
<h2>Film List</h2>
{list.length === 0 && <p>No films...</p>}
{list.map((film, index) => (
<p key={film.title}>
<NavLink to={`/films/${index + 1}`} className={({isActive}) => (isActive ? "activeLink" : 'none')}>
{film.title}
</NavLink>
</p>
))}
</div>
<div className="details">
<Routes>
<Route path="/films/:id" element={<Film findFilm={findFilm} />} />
</Routes>
</div>
</>
)
}
Film.js
import { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import React from 'react'
export const Film = ({ findFilm }) => {
const [film, setFilm] = useState(null);
const { id } = useParams();
useEffect(() => {
setFilm(findFilm(id));
}, [findFilm, id]);
let details = (
<>
<p>{film && film.title}</p>
<p>{film && film.release_date}</p>
</>
);
return (
<>
<h2>Film Details</h2>
{film && details}
</>
)
}
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './components/App/App';
import { BrowserRouter } from 'react-router-dom'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
Main
component is being rendered in App
component. Please look in the code either I will have to make css file className results to display data or it's a routing problem why code is not able to display data in the page planet is sub component of Planet.
答案1
得分: 2
嵌套的 Routes
组件会相对于父级 Route
组件构建它们的路由。如果 Films
组件在 path="/films/*"
上渲染,那么所有后代路由将相对于 "/films"。后代路由 path="/films/:id"
解析为 "/films/films/:id",这可能不是您想要的。
移除后代路由的前导 "/films" 段。
<Routes>
<Route path="/:id" element={<Film findFilm={findFilm} />} />
</Routes>
英文:
Nested Routes
components build their routes relative to the parent Route
component. If the Films
component is rendered on path="/films/*"
then all descendent routes will be relative from "/films"
. A descendent route path="/films/:id"
resolves to "/films/films/:id"
which probably not what you intended.
Remove the leading "/films"
segment of the descendent routes.
<Routes>
<Route path="/:id" element={<Film findFilm={findFilm} />} />
</Routes>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论