recherche

Maison  >  Questions et réponses  >  le corps du texte

Qu'est-ce qui fait échouer la transition (myComponent) dans cette application React 18 ?

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;

Bac à sable

Il y a un bac à sable, le code est ici.

Question

Remplacer export default myComponent 更改为 export default transition(myComponent) rendra le composant impossible à rendre.

Modifier

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 .

Question

  1. Qu'est-ce que j'ai fait de mal ?
  2. Quel est le moyen le plus fiable de résoudre ce problème ?

P粉717595985P粉717595985244 Il y a quelques jours366

répondre à tous(2)je répondrai

  • P粉432930081

    P粉4329300812024-03-29 16:08:40

    L'erreur se produit à cause du contraire de transition函数返回的函数没有渲染组件;它返回 undefined.

    const transition = (OgComponent) => {
      // the function below does not return the component
      return () => {
        <>
          <OgComponent />
          ...
        </>
      }
    }
    

    Pour résoudre ce problème, vous pouvez supprimer les accolades ou définir un retour explicite pour la fonction interne :

    Retour explicite

    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 />
          </>
        )
    
      }
    }
    

    répondre
    0
  • P粉764003519

    P粉7640035192024-03-29 10:18:19

    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 :

    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;
    };

    Vous pouvez ensuite l'appeler en passant le composant page comme TransitioningComponent 参数传递给 withTransition et en l'exportant à partir d'un fichier jsx.

    // Movielist.jsx line 41
    export default withTransition(Movielist);

    Voir le bac à sable du code fonctionnel ici

    Voici un gif en action

    Cela est dû à l'expiration de la clé API stockée dans le fichier

    que 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. 404 错误是由于codesandbox .env

    J'espère que cette réponse vous aidera !

    répondre
    0
  • Annulerrépondre