简体   繁体   English

React 路由器 dom 动态路由

[英]React router dom dynamic routing

I am doing a React.js project.我正在做一个 React.js 项目。 I am retrieving dat from the Star Wars API rendering a list of films on the screen and now I am trying to route every film to its own page through react-router-dom.我正在从星球大战 API中检索 dat,在屏幕上呈现电影列表,现在我试图通过 react-router-dom 将每部电影路由到自己的页面。 Unfortunately, I am not able to make it work.不幸的是,我无法让它工作。 it crash when I try to routing dynamically.当我尝试动态路由时它崩溃了。

UPDATE AFTER ANSWER OF REZA回复 REZA 后的更新

This is the App.js:这是 App.js:

import './App.css';    
import { Route, Routes } from "react-router-dom";    
import Home from './components/Home';
import ItemContainer from './components/ItemContainer';
import Navbar from './components/Navbar';

function App() {
  return (
      <>
      <Navbar />
        <Routes>
            <Route exact path='/' element={<Home />} />
            <Route exact path="/:movieId" element={<ItemContainer />} />
        </Routes> 
        </> 
  );
}    
export default App;

This is the ItemContainer:这是 ItemContainer:

import { useEffect, useState } from "react";    
import MovieDetail from "../MovieDetail";
import { useParams } from "react-router-dom";    
const ShowMovie = (movieId) => {
    const [result, setResult] = useState([]);

    const fetchData = async () => {
        const res = await fetch("https://www.swapi.tech/api/films/");
        const json = await res.json();
        setResult(json.result);
    }
    useEffect(() => {
        fetchData();
    }, []);
    return new Promise((res) => 
    res(result.find((value) => value.properties.title === movieId)))
}

const ItemContainer = () => {
    const [films, setFilms] = useState([]);
    const { movieId } = useParams([]);
    console.log('params movieId container', movieId)

    useEffect(() => {
        ShowMovie(movieId).then((value) => {
            setFilms(value.properties.title)
        })
    }, [movieId])
    return (
            <MovieDetail key={films.properties.title} films={films} />
    );
}     
export default ItemContainer;

The console.log doesn't give anything. console.log 没有给出任何东西。 Also, this is the whole code in sandbox .此外,这是sandbox中的全部代码。

Modify App.js like this:像这样修改 App.js:

function App() {
  return (
    <>
      <Navbar />
      <Routes>
        <Route exact path="/" element={<Home />} />
        <Route exact path="/:movieId" element={<ItemContainer />} />
      </Routes>
    </>
  );
}

ShowMovie is declared like a React component, but used like a utility function. ShowMovie被声明为一个 React 组件,但使用起来却像一个实用程序 function。 You shouldn't directly invoke React function components.你不应该直接调用 React function 组件。 React functions are also to be synchronous, pure functions. React 函数也应该是同步的纯函数。 ShowMovie is returning a Promise with makes it an asynchronous function. ShowMovie正在返回一个Promise ,使其成为异步 function。

Convert ShowMovie into a utility function, which will basically call fetch and process the JSON response.ShowMovie转换为实用程序 function,它基本上会调用fetch并处理 JSON 响应。

import { useEffect, useState } from "react";    
import MovieDetail from "../MovieDetail";
import { useParams } from "react-router-dom";

const showMovie = async (movieId) => {
  const res = await fetch("https://www.swapi.tech/api/films/");
  const json = await res.json();
  const movie = json.result.find((value) => value.properties.title === movieId));

  if (!movie) {
    throw new Error("No match found.");
  }

  return movie;
}

const ItemContainer = () => {
  const [films, setFilms] = useState({});
  const { movieId } = useParams();

  useEffect(() => {
    console.log('params movieId container', movieId);

    showMovie(movieId)
      .then((movie) => {
        setFilms(movie.properties.title);
      })
      .catch(error => {
        // handle error/log it/show message/ignore/etc...

        setFilms({}); // maintain state invariant of object
      });
  }, [movieId]);

  return (
    <MovieDetail key={films.properties?.title} films={films} />
  );
};

export default ItemContainer;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM