我正在关注这个 hackernoon 指南 https://hackernoon.com/animated-page-transitions-with-react-router-4-reacttransitiongroup-and-animated-1ca17bd97a1a为了在路线更改时将进入和离开动画应用于我的 react 组件。我显然已经调整了代码以适合我的网站,并决定不使用动画,而只使用纯 CSS。现在我只是用 console.log 语句测试代码,我注意到 componentWillEnter 和 componentWillLeave 没有在路由更改时被调用。此外,componentWillAppear 只被调用一次。
这里是各个组件的相关代码,包括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;
应用程序.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')
);
slider .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;
最佳答案
尝试使用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'));
关于javascript - 为什么 react-transition-group 在路由更改时不调用 componentWillEnter 或 componentWillLeave?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45376845/