Rumah > Soal Jawab > teks badan
Saya telah membangunkan SPA menggunakan React 18 dan Movie Database (TMDB) API.
Saya kini menambah peralihan antara laluan(halaman) dengan bantuan Framer Motion.
Untuk melakukan ini, saya mencipta fail /src
中添加了一个 transition.js
dengan kandungan berikut:
import { motion } from "framer-motion"; const transition = (OgComponent) => { return () => { <> <OgComponent /> <motion.div className="slide-in" initial={{ opacity: 0, x: '-100px' }} animate={{ opacity: 1, x: 0, transition: { duration: 0.3 } }} exit={{ opacity: 0, x: 0, transition: { duration: 0.3 } }} > <motion.div /> </> } } export default transition;
Saya menggunakan import transition from '../../transition'
将上述 transition
untuk mengimport ke dalam komponen aplikasi dan membungkus komponen yang dieksport ke dalamnya. Lihat komponen Movielist sebagai contoh:
import { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; import axios from 'axios'; import Moviecard from '../Moviecard/Moviecard'; import transition from '../../transition'; function Movielist({ page_title, listMovies }) { const API_URL = 'https://api.themoviedb.org/3'; const location = useLocation(); const [movies, setMovies] = useState([]); const getMovies = async () => { const { data: { results } } = await axios.get(`${API_URL}/movie/${listMovies}`, { params: { api_key: process.env.REACT_APP_API_KEY } }); setMovies(results); } const displayMovies = () => { return movies.map(movie => ( <Moviecard key={movie.id} movie={movie} /> )) } useEffect(() => { getMovies(); }, [location]) return ( <> <h1 className="page-title">{ page_title }</h1> <div className="row movie-list"> { displayMovies() } </div> </> ); } export default transition(Movielist);
Dalam App.js saya mempunyai laluan "biasa":
import { Routes, Route } from 'react-router-dom'; import Topbar from './components/Topbar/Topbar'; import Footer from './components/Footer/Footer'; import Movielist from './components/Movielist/Movielist'; import Moviedetails from './components/Moviedetails/Moviedetails'; import Actordetails from './components/Actordetails/Actordetails'; function App() { return ( <div className="App"> <Topbar /> <div className="container"> <Routes> <Route path="/" element={<Movielist page_title="Now playing" listMovies="now_playing" />} /> <Route path="/top-rated" element={<Movielist page_title="Top rated" listMovies="top_rated" />} /> <Route path="/movie/:id" element={<Moviedetails />} /> <Route path="/actor/:id" element={<Actordetails />} /> </Routes> </div> <Footer /> </div> ); } export default App;
Ada kotak pasir, kodnya sini.
Menggantikan export default myComponent
更改为 export default transition(myComponent)
akan menjadikan komponen tidak dapat ditayangkan.
Buat ini...
const transition = (OgComponent) => { return () => ( <> <OgComponent /> <motion.div className="slide-in" initial={{ opacity: 0, x: 0 }} animate={{ opacity: 1, x: 100, transition: { duration: 0.5 } }} exit={{ opacity: 0, x: 0, transition: { duration: 0.5 } }} /> </> ); };
membuang ini ralat :
Permintaan gagal, kod status 404 AxiosError: Permintaan gagal Kod status 404 Apabila diselesaikan (http://localhost:3000/static/js/bundle.js:63343:12) Dalam XMLHttpRequest.onloadend (http://localhost:3000/static/js/bundle.js:62034:66)
Semuanya berfungsi dengan baik sehingga saya cuba menambah peralihan halaman yang lancar .
P粉4329300812024-03-29 16:08:40
Ralat berlaku kerana sebaliknya daripada transition
函数返回的函数没有渲染组件;它返回 undefined
.
const transition = (OgComponent) => { // the function below does not return the component return () => { <> <OgComponent /> ... </> } }
Untuk menyelesaikan masalah ini, anda boleh mengeluarkan pendakap kerinting atau menentukan pulangan eksplisit untuk fungsi dalaman:
Kembalikan secara eksplisit
const transition = (OgComponent) => { return () => { return ( <> <OgComponent /> <motion.div className="slide-in" initial={{ opacity: 0, x: 0 }} animate={{ opacity: 1, x: 100, transition: { duration: 0.5 } }} exit={{ opacity: 0, x: 0, transition: { duration: 0.5 } }} /> <motion.div /> </> ) } }
P粉7640035192024-03-29 10:18:19
Saya rasa apa yang anda mahukan (nampaknya itulah yang anda mahu lakukan, kerja bagus!) ialah mencipta 高阶组件
将您的页面组件包装在 <来自 framermotion
的 code>motion.div supaya ia boleh mengubah komponen anda untuk anda.
Cuba tukar 转换
kod anda kepada:
import React from "react"; import { motion } from "framer-motion"; export const withTransition = (TransitioningComponent) => { class WithTransition extends React.Component { render() { return ( <motion.div className="slide-in" initial={{ opacity: 0, x: '-100px' }} animate={{ opacity: 1, x: 0, transition: { duration: 0.3 } }} exit={{ opacity: 0, x: 0, transition: { duration: 0.5 } }} > <TransitioningComponent {...this.props} /> </motion.div> ); } } WithTransition.displayName = `WithTransition(${ TransitioningComponent.displayName || TransitioningComponent.name })`; return WithTransition; };
Anda kemudian boleh memanggilnya dengan menghantar komponen halaman sebagai TransitioningComponent
参数传递给 withTransition
dan mengeksportnya daripada fail jsx.
// Movielist.jsx line 41 export default withTransition(Movielist);
Lihat kotak pasir kod berfungsi di sini
Berikut ialah gifnya dalam tindakanIni disebabkan oleh tamat tempoh kunci API yang disimpan dalam fail
yang anda terus terima daripada axios. Saya rasa pertanyaan itu gagal kerana respons 403 - Access Denied. Saya belum menyemak, tetapi ini paling masuk akal kepada saya. Saya telah mengulas beberapa panggilan axios supaya anda dapat melihat transformasi berfungsi. 404
错误是由于codesandbox .env