Mengapakah data untuk panggilan API tidak ditentukan?
P粉726133917
P粉726133917 2024-01-29 13:46:53
0
1
459

Saya membina apl web filem menggunakan React.js. Data berfungsi dengan baik apabila saya memanggilnya pada API. Walau bagaimanapun, apabila saya cuba menukar halaman melalui panggilan API id, data menjadi tidak ditentukan. Saya menggunakan kit alat Redux untuk memanggil data.

Tetapi apabila saya cuba menekan kad, salah satu halaman yang saya sediakan untuk mendapatkan data daripada kad yang dipilih berlaku seperti gambar di bawah

Saya cuba menyemak log konsol dan hasilnya adalah seperti berikut.

Kalau nak semak kod

.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

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

Saya cuba melakukan apa yang dirujuk oleh laman web ini.

Jika saya klik pada beberapa kad, hasilnya akan menjadi seperti ini

Tetapi apa yang saya dapat ialah ini dan ini

P粉726133917
P粉726133917

membalas semua(1)
P粉716228245

Berdasarkan apa yang saya lihat, Masalahnya sepatutnya dengan panggilan api ini

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
}

})

sepatutnya

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
}
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan