React Router v4动画转换示例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React Router v4动画转换示例相关的知识,希望对你有一定的参考价值。
动画转换示例provided in the v4 docs对我来说似乎有点复杂,因为它描绘了淡入淡出相同的组件并调整背景颜色。
我正在尝试将这种技术应用到一个更真实的例子中,将一个组件淡出另一个组件,但是我无法让它正常工作(它似乎只是淡出第一个,然后第二个弹出in,此转换只能以一种方式工作(后退按钮不会转换)。
这是我的代码,它使用示例中的精简版MatchWithFade
:
import React from 'react';
import { TransitionMotion, spring } from 'react-motion'
import { HashRouter, Match, Miss } from 'react-router';
import Home from './components/Home';
import Player from './components/Player';
import FormConfirmation from './components/FormConfirmation';
const App = () => (
<HashRouter>
<div className="App">
<MatchWithFade exactly pattern="/" component={Home} />
<MatchWithFade pattern="/player/:playerId" component={Player} />
<MatchWithFade pattern="/entered" component={FormConfirmation} />
<Miss render={(props) => (
<Home players={Players} prizes={Prizes} {...props} />
)} />
</div>
</HashRouter>
);
const MatchWithFade = ({ component:Component, ...rest }) => {
const willLeave = () => ({ zIndex: 1, opacity: spring(0) })
return (
<Match {...rest} children={({ matched, ...props }) => (
<TransitionMotion
willLeave={willLeave}
styles={matched ? [ {
key: props.location.pathname,
style: { opacity: spring(1) },
data: props
} ] : []}
>
{interpolatedStyles => (
<div>
{interpolatedStyles.map(config => (
<div
key={config.key}
style={{...config.style}}
>
<Component {...config.data}/>
</div>
))}
</div>
)}
</TransitionMotion>
)}/>
)
}
export default App;
我意识到这个问题几乎与this one重复,但是有一个接受的答案实际上没有回答这个问题。
react-motion
不适合大型应用。请改用react-transition-group
。
因为react-motion
使用javascript
来执行转换。在进行API
调用时,转换将跨越路径(在js
中同步调用)并在路由到新页面时使转换滞后。 react-transition-group
使用CSS
进行过渡。
v4 docs已经转移到react-transition-group
,所以你可以考虑做同样的事情。
关于“淡入淡出相同的组件”,它与Component的实例并不完全相同。两个实例同时存在并且可以提供交叉淡入淡出。 react-motion
docs说“TransitionMotion
保持c
”,我想react-transition-group
是相同的。
这是使用来自“react-addons-css-transition-group”的react 16和ReactCSSTransitionGroup的更新解决方案
index.js
import React, { Component } from "react";
import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import { render } from "react-dom";
import "./main.css";
function* continuosArrayIterator(arr) {
let idx = 0;
while (idx < arr.length) {
let ret = arr[idx];
idx++;
if (idx === arr.length) {
idx = 0;
}
yield ret;
}
}
class App extends Component {
constructor() {
super();
this.clickHandler = this.clickHandler.bind(this);
this.items = [
{
id: 1,
text: "item1",
img: "https://mirrors.creativecommons.org/presskit/icons/cc.large.png"
},
{
id: 2,
text: "item2",
img: "https://mirrors.creativecommons.org/presskit/icons/by.large.png"
},
{
id: 3,
text: "item3",
img: "https://mirrors.creativecommons.org/presskit/icons/nc.large.png"
},
{
id: 4,
text: "item4",
img:
"https://mirrors.creativecommons.org/presskit/icons/nc-eu.large.png"
}
];
this.imageIterator = continuosArrayIterator(this.items);
this.state = {
image: this.imageIterator.next().value
};
}
clickHandler(event) {
return this.setState({
image: this.imageIterator.next().value
});
}
render() {
return (
<div>
<button onClick={this.clickHandler}>Next Image</button>
<ReactCSSTransitionGroup
transitionAppear={true}
transitionLeaveTimeout={500}
transitionEnterTimeout={500}
className="container"
transitionName="example"
>
<div
key={this.state.image.id}
style={{
position: "absolute",
backgroundImage: `url(${this.state.image.img}`,
backgroundSize: "auto 100px",
height: "100px",
width: "100px"
}}
/>
</ReactCSSTransitionGroup>
</div>
);
}
}
render(<App />, document.getElementById("root"));
的main.css
.container {
position: absolute;
}
.example-enter {
opacity: 0.01;
}
.example-enter.example-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
.example-leave {
opacity: 1;
}
.example-leave.example-leave-active {
opacity: 0.01;
transition: opacity 500ms ease-in;
}
.example-appear {
opacity: 0.01;
}
.example-appear.example-appear-active {
opacity: 1;
transition: opacity 0.5s ease-in;
}
以上是关于React Router v4动画转换示例的主要内容,如果未能解决你的问题,请参考以下文章
React-router-dom (v6) 和 Framer Motion (v4)