无法在React中显示电影列表数据。

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

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 &quot;/films&quot; 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 &#39;react-router-dom&#39;
import { Films } from &#39;../Films/Films&#39;
import { Home } from &#39;../Home/Home&#39;

export const Main = (props) =&gt; {
  return (
    &lt;div className=&#39;mainContent&#39;&gt;
      &lt;Routes&gt;
        &lt;Route path=&quot;/films/*&quot; element={&lt;Films /&gt;}&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/planets/*&quot; element={&lt;Planets /&gt;}&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/people&quot; element={&lt;People list={people} /&gt;}&gt;
          &lt;Route path=&quot;:id&quot; element={&lt;Person list={people} /&gt;}&gt;&lt;/Route&gt;
          {/* Person is passed prop with fetch results */}
        &lt;/Route&gt;
        &lt;Route path=&quot;*&quot; element={&lt;Home /&gt;}&gt;&lt;/Route&gt;
      &lt;/Routes&gt;
    &lt;/div&gt;
  )
}

Films.js

import React from &#39;react&#39;
import { NavLink, Route, Routes } from &#39;react-router-dom&#39;;
import { Film } from &#39;../Film/Film&#39;
import &#39;./films.css&#39;

export const Films = (props) =&gt; {
  const [list, setList] = useState([]);

  useEffect(() =&gt; {
    (function getFilms() {
      let url = &#39;https://swapi.dev/api/films/&#39;;
      fetch(url)
        .then((resp) =&gt; {
          if (!resp.ok) throw new Error(resp.statusText);
          return resp.json();
        })
        .then((data) =&gt; {
          setList(data.results);
        })
        .catch(console.warn);
    })();
  }, []);

  function findFilm(id) {
    return list.find((item, index) =&gt; parseInt(id) === index + 1);
  }
  
  return (
    &lt;&gt;
      &lt;div className=&quot;results&quot;&gt;
        &lt;h2&gt;Film List&lt;/h2&gt;

        {list.length === 0 &amp;&amp; &lt;p&gt;No films...&lt;/p&gt;}
        {list.map((film, index) =&gt; (
          &lt;p key={film.title}&gt;
            &lt;NavLink to={`/films/${index + 1}`} className={({isActive}) =&gt; (isActive ? &quot;activeLink&quot; : &#39;none&#39;)}&gt;
              {film.title}
            &lt;/NavLink&gt;
          &lt;/p&gt;
        ))}
      &lt;/div&gt;

      &lt;div className=&quot;details&quot;&gt;
        &lt;Routes&gt;
          &lt;Route path=&quot;/films/:id&quot; element={&lt;Film findFilm={findFilm} /&gt;} /&gt;
        &lt;/Routes&gt;  
      &lt;/div&gt;
    &lt;/&gt;
  )
}

Film.js

import { useState, useEffect } from &#39;react&#39;;
import { useParams } from &#39;react-router-dom&#39;;
import React from &#39;react&#39;

export const Film = ({ findFilm }) =&gt; {
  const [film, setFilm] = useState(null);
  const { id } = useParams();
  
  useEffect(() =&gt; {
    setFilm(findFilm(id));
  }, [findFilm, id]);

  let details = (
    &lt;&gt;
      &lt;p&gt;{film &amp;&amp; film.title}&lt;/p&gt;
      &lt;p&gt;{film &amp;&amp; film.release_date}&lt;/p&gt;
    &lt;/&gt;
  );

  return (
    &lt;&gt;
      &lt;h2&gt;Film Details&lt;/h2&gt;
      {film &amp;&amp; details}
    &lt;/&gt;
  )
}

index.js

import React from &#39;react&#39;;
import ReactDOM from &#39;react-dom/client&#39;;
import App from &#39;./components/App/App&#39;;
import { BrowserRouter } from &#39;react-router-dom&#39;

const root = ReactDOM.createRoot(document.getElementById(&#39;root&#39;));
root.render(
  &lt;React.StrictMode&gt;
    &lt;BrowserRouter&gt;
      &lt;App /&gt;
    &lt;/BrowserRouter&gt;
  &lt;/React.StrictMode&gt;
);

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.

无法在React中显示电影列表数据。

答案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=&quot;/films/*&quot; then all descendent routes will be relative from &quot;/films&quot;. A descendent route path=&quot;/films/:id&quot; resolves to &quot;/films/films/:id&quot; which probably not what you intended.

Remove the leading &quot;/films&quot; segment of the descendent routes.

&lt;Routes&gt;
  &lt;Route path=&quot;/:id&quot; element={&lt;Film findFilm={findFilm} /&gt;} /&gt;
&lt;/Routes&gt;

huangapple
  • 本文由 发表于 2023年3月8日 15:07:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75670179.html
匿名

发表评论

匿名网友

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

确定