Heim  >  Fragen und Antworten  >  Hauptteil

Warum sind die Daten für API-Aufrufe undefiniert?

Ich habe mit React.js eine Film-Web-App erstellt. Die Daten funktionieren einwandfrei, wenn ich sie über die API aufrufe. Wenn ich jedoch versuche, die Seite per API-Aufruf zu wechseln id, werden die Daten undefiniert. Zum Aufrufen der Daten verwende ich das Redux-Toolkit.

Aber wenn ich versuche, auf die Karte zu drücken, passiert eine der Seiten, die ich eingerichtet habe, um die Daten von der ausgewählten Karte abzurufen, wie im Bild unten

Ich habe versucht, das Konsolenprotokoll zu überprüfen und die Ergebnisse sind wie folgt.

Wenn Sie den Code überprüfen möchten

.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

Details.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>,
)

Ich versuche, das zu tun, worauf sich diese Website bezieht.

Wenn ich auf einige Karten klicke, sieht das Ergebnis so aus

Aber was ich bekomme, ist Folgendes und das

P粉726133917P粉726133917264 Tage vor431

Antworte allen(1)Ich werde antworten

  • P粉716228245

    P粉7162282452024-01-30 12:22:42

    根据我所看到的, 问题应该出在这个 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
    }

    })

    应该是

    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
    }

    Antwort
    0
  • StornierenAntwort