J'ai développé SPA en utilisant React 18 et L'API Movie Database (TMDB).
J'ajoute maintenant des transitions entre itinéraires(pages) avec l'aide de Framer Motion.
Pour ce faire, j'ai créé un fichier /src
中添加了一个 transition.js
avec le contenu suivant :
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;
J'utilise import transition from '../../transition'
将上述 transition
pour importer dans les composants de l'application et y envelopper les composants exportés. Voir le composant Movielist à titre d'exemple :
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);
Dans App.js j'ai la route "normale":
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;
Il y a un bac à sable, le code est ici.
Remplacer export default myComponent
更改为 export default transition(myComponent)
rendra le composant impossible à rendre.
Fais ça...
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 } }} /> </> ); };
lance cette erreur :
La demande a échoué, code d'état 404 AxiosError : la demande a échoué Code d'état 404 Une fois résolu (http://localhost:3000/static/js/bundle.js:63343:12) Dans XMLHttpRequest.onloadend (http://localhost:3000/static/js/bundle.js:62034:66)
Tout fonctionnait bien jusqu'à ce que j'essaye d'ajouter une transition de page fluide .
L'erreur se produit à cause du contraire de
transition
函数返回的函数没有渲染组件;它返回undefined
.Pour résoudre ce problème, vous pouvez supprimer les accolades ou définir un retour explicite pour la fonction interne :
Retour explicite
Je pense que ce que vous voulez (on dirait que c'est ce que vous voulez faire, bon travail !) c'est créer un
高阶组件
将您的页面组件包装在 framermotion 的 code>motion.div pour qu'il puisse transformer votre composant pour vous.Essayez de changer votre
转换
code par :Vous pouvez ensuite l'appeler en passant le composant page comme
TransitioningComponent
参数传递给withTransition
et en l'exportant à partir d'un fichier jsx.Voir le bac à sable du code fonctionnel ici
Voici un gif en actionque vous continuez à recevoir d'axios. Je pense que la requête a échoué en raison d'une réponse 403 - Accès refusé. Je n'ai pas vérifié, mais c'est ce qui me semble le plus logique. J'ai commenté certains des appels axios afin que vous puissiez voir la transformation fonctionner.
J'espère que cette réponse vous aidera !404
错误是由于codesandbox.env