Pourquoi les données des appels d'API ne sont-elles pas définies ?
P粉726133917
P粉726133917 2024-01-29 13:46:53
0
1
456

J'ai créé une application Web de films en utilisant React.js. Les données fonctionnent bien lorsque je les appelle sur l'API. Cependant, lorsque j'essaie de changer de page via un appel API id, les données deviennent indéfinies. J'utilise la boîte à outils Redux pour appeler les données.

Mais lorsque j'essaie d'appuyer sur la carte, l'une des pages que j'ai configurées pour obtenir les données de la carte sélectionnée se produit comme l'image ci-dessous

J'ai essayé de vérifier le journal de la console et les résultats sont les suivants.

Si vous souhaitez vérifier le code

.env

sorry i can share api key
VITE_BASE_URL=https://api.themoviedb.org/3
VITE_IMG_PATH=https://image.tmdb.org/t/p/w500
VITE_VIDEO_PATH=https://api.themoviedb.org/3/movie

api.js

import Axios from 'axios'

export const movieList = Axios.create({
    baseURL: `${import.meta.env.VITE_BASE_URL}`
})

action.js

import { createAsyncThunk } from "@reduxjs/toolkit";
import { movieList } from "../../service/api/api";

export const fetchMovieAll = createAsyncThunk('movie/fetchMovieAll', async() => {
    try {
        const api = `api_key=${import.meta.env.VITE_TMDB_KEY}`
        const respone = await movieList.get(`discover/movie?${api}`)
        return respone.data.results
    } catch (error) {
        return error
    }
})

export const fetchMovie = createAsyncThunk('movie/fetchMovie', async(id) => {
    try {
        const respone = await movieList.get(`/movie/${id}?api_key=${import.meta.env.VITE_TMDB_KEY}`)
        return respone.data.results
    } catch (error) {
        return error
    }
})

slice.js

import {createSlice} from '@reduxjs/toolkit'
import * as movieAction from '../action'

const movieDb = createSlice({
    name: 'movieDb',
    initialState: {
        loading: false,
        data: [],
        entity: {
            id: null,
            title: '',
            release_date: '',
            popularity: '',
            poster_path: '',
            overview: '',
            vote_average: '',
            backdrop_path: ''
        },
        error: null,
    },
    extraReducers: (builder) => 
        builder.addCase(movieAction.fetchMovieAll.pending, (state) => {
            state.loading = true
        })
        .addCase(movieAction.fetchMovieAll.fulfilled, (state, action) => {
            state.loading = false,
            state.data = action.payload
        })
        .addCase(movieAction.fetchMovieAll.rejected, (state) => {
            state.loading = true,
            state.error = action.payload
        })

        .addCase(movieAction.fetchMovie.pending, (state) => {
            state.loading = true
        })
        .addCase(movieAction.fetchMovie.fulfilled, (state, action) => {
            state.loading = false,
            state.entity = action.payload
        })
        .addCase(movieAction.fetchMovie.rejected, (state) => {
            state.loading = true,
            state.error = action.payload
        })
})

export default movieDb.reducer;

store.js

import { configureStore } from "@reduxjs/toolkit";
import movieDbReducer from '../slice'

export default configureStore({
    reducer: {
        movieDb: movieDbReducer,
    }
})

CardMovie.jsx

import React, { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { fetchMovieAll } from '../../../manage/action'
import style from './style.module.css'
import { useNavigate } from 'react-router-dom'

function CardMovie() {

    const dispatch = useDispatch()
    const {data} = useSelector((state) => state.movieDb)
    const navigate = useNavigate()

    const fetchDataMovie = async() => {
        dispatch(fetchMovieAll())
    }

    const goToDetail = (id) => {
        navigate(`/detail/${id}`)
    }

    useEffect(() => {
        fetchDataMovie()
        console.log(data)
    },[])

    return (
        <>
            {data.map((item) => {
                return (
                    <div key={item.id} className={style['main-card']} onClick={() => goToDetail(item.id)}>
                        <div className={style['card-content']}>
                            <img src={`${import.meta.env.VITE_IMG_PATH}${item.poster_path}`} alt="poster" />
                            <div className={style['card-title']}>
                                <p>{item.title}</p>
                            </div>
                        </div>
                    </div>
                )
            })}
        </>
    )
}

export default CardMovie

Détails.jsx

import React, { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useNavigate, useParams } from 'react-router-dom'
import { fetchMovie } from '../../manage/action'

function Detail() {

    const {id} = useParams()
    const dispatch = useDispatch()
    // const navigate = useNavigate()
    const {entity} = useSelector((state) => state.movieDb)
    const fetchDataMovie = async(movieId) => {
        dispatch(fetchMovie(movieId))
    }

    useEffect(() => {
        fetchDataMovie(id)
        console.log(entity)
    },[])

    return (
        <>
            <div>
                <h1>Detail</h1>
                {/* <h5>{entity.title}</h5> */}
            </div>
        </>
    )
}

export default Detail

App.jsx

import Home from "./page/Home"
import Genre from "./page/Genre"
import Detail from "./page/Detail"
import './App.css'
import {Outlet, RouterProvider, createBrowserRouter} from 'react-router-dom'

function App() {

  const router = createBrowserRouter([
    {
      path: '/',
      children: [
        {
          index: true,
          element: <Home/>
        },
        {
          path: 'genre',
          element: <Genre/>
        },
        {
          path: 'detail/:id',
          element: <Detail/>
        }
      ]
    }
  ])

  return (
    <>
      <RouterProvider router={router}/>
      <Outlet/>
    </>
  )
}

export default App

index.jsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap/dist/js/bootstrap.js'
import { Provider } from 'react-redux'
import store from './manage/store/index.js'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
)

J'essaie de faire ce à quoi ce site Web fait référence.

Si je clique sur certaines cartes, le résultat sera comme ceci

Mais ce que j'obtiens, c'est ceci et ça

P粉726133917
P粉726133917

répondre à tous(1)
P粉716228245

D'après ce que j'ai vu, Le problème devrait venir de cet appel API

export const fetchMovie = createAsyncThunk('movie/fetchMovie', async(id) => {
try {
    const respone = await movieList.get(`/movie/${id}?api_key=${import.meta.env.VITE_TMDB_KEY}`)
    return respone.data.results
} catch (error) {
    return error
}

})

devrait être

export const fetchMovie = 
createAsyncThunk('movie/fetchMovie', async(id) => {
try {
const respone = await movieList.get(`/movie/${id}? api_key=${import.meta.env.VITE_TMDB_KEY}`)
return respone.data
} catch (error) {
return error
}
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal