Rumah > Soal Jawab > teks badan
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粉7162282452024-01-30 12:22:42
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 }