1

私は、このハケナーンガイドhttps://hackernoon.com/animated-page-transitions-with-react-router-4-reacttransitiongroup-and-animated-1ca17bd97a1aに従っています。ルートが変更されたときに反応コンポーネントにアニメーションを入力して放置します。私は明らかに自分のサイトに合うようにコードを適合させ、Animatedではなく純粋なCSSを使用することに決めました。今、私はconsole.logステートメントでコードをテストしていますが、コンポーネントの変更点と変更点にcomponentWillEnterとcomponentWillLeaveが呼び出されていないことに気付きました。また、componentWillAppearは一度だけ呼び出されます。ここなぜ、react-transition-groupはroute changeでcomponentWillEnterもcomponentWillLeaveも呼び出さないのですか?

はApp.jsとindex.jsを含む各コンポーネントの関連するコードは、次のとおりです

アニメーションラッパー:

import React, {Component} from "react"; 
import styles from '../styles/AnimatedWrapper.css'; 

const AnimatedWrapper = WrappedComponent => 
    class AnimatedWrapper extends Component { 
    componentWillAppear(cb) { 
     console.log('componentWillAppear'); 
     cb(); 
    } 
    componentWillEnter(cb) { 
     console.log('componentWillEnter'); 
     cb(); 
    } 
    componentWillLeave(cb) { 
     console.log('componentWillLeave'); 
     cb(); 
    } 
    render() { 
     return (
     <div id="animated-wrapper" className={styles.animatedPageWrapper}> 
      <WrappedComponent {...this.props}/> 
     </div> 
    );} 
    }; 

export default AnimatedWrapper; 

App.js:

import React, { Component } from 'react'; 
import { Route, Switch } from 'react-router-dom'; 
import TransitionGroup from "react-transition-group/TransitionGroup"; 

import Navbar from "./components/Navbar"; 
import Footer from "./components/Footer"; 
import Slider from "./components/Slider"; 
import ComingSoon from "./components/ComingSoon"; 

const firstChild = props => { 
    const childrenArray = React.Children.toArray(props.children); 
    return childrenArray[0] || null; 
} 

class App extends Component { 
    render() { 
    return (
     <div className="App"> 
     <Navbar /> 
     <Switch> 
      <Route 
      path="/coming-soon" 
      children={({ match, ...rest }) => (
       <TransitionGroup component={firstChild}> 
       {match && <ComingSoon {...rest} />} 
       </TransitionGroup> 
     )}/> 
      <Route 
      path="/" 
      children={({ match, ...rest }) => (
       <TransitionGroup component={firstChild}> 
       {match && <Slider {...rest} />} 
       </TransitionGroup> 
     )}/> 
     </Switch> 
     <Footer /> 
     </div> 
    ); 
    } 
} 

export default App; 

index.js :

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { BrowserRouter } from 'react-router-dom'; 
import App from './App'; 
import './index.css'; 

ReactDOM.render(
    <BrowserRouter> 
    <App /> 
    </BrowserRouter>, 
    document.getElementById('root') 
); 

スリder.js:

import React, { Component } from 'react'; 
import _ from 'lodash'; 

// components 
import AnimatedWrapper from './AnimatedWrapper'; 
import Separator from './Separator'; 

// styles 
import styles from '../styles/Slider.css'; 

// images 
import Apartment from "../../public/images/apartment.jpg"; 
import Floor from "../../public/images/floor.jpg"; 
import Furniture from "../../public/images/furniture.jpg"; 
import Kitchen1 from "../../public/images/kitchen.jpg"; 
import Kitchen2 from "../../public/images/kitchen-2.jpg"; 

class SliderComponent extends Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     currentSlide: 0, 
     slides: [Apartment, Floor, Furniture, Kitchen1, Kitchen2] 
    }; 
    } 

    componentDidMount() { 
    this.zoomAnimation(); 
    this.slideContentAnimation(); 

    this.sliderInterval = setInterval(() => { 
     if (this.state.currentSlide === 4) { 
     if (this.refs.slider) { 
      this.setState({ currentSlide: 0 }); 
     } 
     } else { 
     if (this.refs.slider) { 
      this.setState({ currentSlide: this.state.currentSlide + 1 }); 
     } 
     } 
    }, 6000); 
    } 

    componentWillUpdate() { 
    const currentContent = document.getElementById(`content-${this.state.currentSlide}`); 
    setTimeout(() => { 
     currentContent.classList.remove(`${styles.currentContent}`); 
    }, 1500); 
    } 

    componentDidUpdate() { 
    this.zoomAnimation(); 
    this.slideContentAnimation(); 
    } 

    setSlide(number) { 
    this.setState({ currentSlide: number }); 
    } 

    zoomAnimation() { 
    setTimeout(() => { 
     const currentSlide = document.getElementById(`slide-${this.state.currentSlide}`); 
     currentSlide.classList.add(`${styles.slideZoom}`); 
    }, 500); 
    } 

    slideContentAnimation() { 
    setTimeout(() => { 
     const currentContent = document.getElementById(`content-${this.state.currentSlide}`); 
     if (currentContent) { 
     currentContent.classList.add(`${styles.currentContent}`); 
     } 
    }, 1500); 
    } 

    renderSlides() { 
    return this.state.slides.map((slide, index) => { 
     const isCurrent = index === this.state.currentSlide; 

     const slideStyle = { 
     backgroundImage: `url(${this.state.slides[index]})` 
     } 

     return (
     <div 
      id={`slide-${index}`} 
      key={`slide-${index}`} 
      className={` 
      ${styles.slide} 
      ${isCurrent ? styles.currentSlide : null} 
      `} 
      style={slideStyle} 
      alt="slide"> 
      <div 
       id={`content-${index}`} 
       key={`content-${index}`} 
       className={` 
       ${styles.content} 
      `}> 
       <h1>{`WE SPECIALIZE IN KITCHENS ${index}`}</h1> 
       <Separator 
       containerWidth={720} 
       circleWidth={5} 
       circleHeight={5} 
       backgroundColor="#fff" 
       lineWidth={350} 
       lineColor="#fff" 
       /> 
       <div 
       className={`${styles['hvr-sweep-to-top']} ${styles.btn}`}> 
       More Information 
       </div> 
      </div> 
     </div> 
    ); 
    }); 
    } 

    renderNavBar() { 
    return (
     <div className={styles.sliderNav}> 
     {_.range(5).map((index) => { 
      return (
      <div 
       key={index} 
       onClick={() => this.setSlide(index)} 
       className={this.state.currentSlide === index ? styles.current : null}> 
      </div> 
     ) 
     })} 
     </div> 
    ) 
    } 

    render() { 
    return (
     <div className={styles.container} ref="slider"> 
     <div className={styles.slidesContainer}> 
      {this.renderSlides()} 
     </div> 

     {this.renderNavBar()} 
     </div> 
    ); 
    } 
} 

const Slider = AnimatedWrapper(SliderComponent); 
export default Slider; 

ComingSoon.js:

import React from 'react'; 
import AnimatedWrapper from './AnimatedWrapper'; 
import styles from '../styles/ComingSoon.css'; 

const ComingSoonComponent = function() { 
    return (
    <div> 
     <div className={styles.mainContent}> 
     <div> 
      <h1 className={styles.mainTitle}>{`Coming Soon`}</h1> 
     </div> 
     </div> 
    </div> 
); 
}; 

const ComingSoon = AnimatedWrapper(ComingSoonComponent); 
export default ComingSoon; 

答えて

-1

react-transition-groupを使用しよう、それが助けになります。

このように使用できます。Example次のメインコードに従ってください:

import { BrowserRouter, Route, Switch, Link } from 'react-router-dom' 
import { CSSTransition, TransitionGroup } from 'react-transition-group' 

const PageFade = (props) => (
    <CSSTransition 
    {...props} 
    classNames="fadeTranslate" 
    timeout={1000} 
    mountOnEnter={true} 
    unmountOnExit={true} 
    /> 
) 

const Layout = ({ children }) => (
    <section> 
    <nav> 
     <ul> 
     <li><Link to="/">Home</Link></li> 
     <li><Link to="/about">About</Link></li> 
     <li><Link to="/topics">Non existing</Link></li> 
     </ul> 
    </nav> 
    <hr /> 
    {children} 
    </section> 
) 

const App = (props) => { 
    const locationKey = props.location.pathname 

    return (
    <Layout> 
    <TransitionGroup> 
     <PageFade key={locationKey}> 
     <section className="fix-container"> 
      <Switch location={props.location}> 
      <Route exact path="/" component={Home} /> 
      <Route exact path="/about" component={About} /> 
      <Route component={NotFound} /> 
      </Switch> 
     </section> 
     </PageFade> 
    </TransitionGroup> 
    </Layout> 
) 
} 

const BasicExample =() => (
    <BrowserRouter> 
    <Route path="/" component={App} /> 
    </BrowserRouter> 
); 

render(<BasicExample />, document.getElementById('root')); 
+0

このリンクは質問に答えるかもしれませんが、ここでは答えの必須部分を含めて参考にしてください。リンクされたページが変更された場合、リンクのみの回答は無効になります。 - [レビューから](/レビュー/低品質の投稿/ 17753934) – Lepidopteron

関連する問題