[英]React smooth transition between different states in a component
我有一個像這樣的簡單組件:
var component = React.createClass({
render: function(){
if (this.props.isCollapsed){
return this.renderCollapsed();
}
return this.renderActive()
},
renderActive: function(){
return (
<div>
...
</div>
);
},
renderCollapsed: function(){
return (
<div>
...
</div>
);
},
});
基本上,當屬性更改時,組件將顯示活動狀態或折疊狀態。
我在想的是,當財產發生變化時,即主動 - >崩潰,或者相反,我希望舊視圖“縮小”或“展開”平滑以顯示新視圖。 例如,如果它處於活動狀態 - >折疊,我希望活動UI縮小到折疊UI的大小,並平滑地顯示它。
我不知道如何達到這個效果。 請分享一些想法。 謝謝!
您可以改為,而不是有條件地渲染組件的兩個不同的最終狀態
在同一組件上切換類 。 您可以使用以下活動和折疊類:
例如:
.active{
-webkit-transition: -webkit-transform .5s linear; // transition of
// 0.5 of a second
height: 200px;
}
.collapsed{
height: 0px;
}
查看此資源以獲取示例
這是一個最小的工作示例:
const collapsible = ({active, toggle}) => <div> <button type="button" onClick={toggle}>Toggle</button> <div className={'collapsible' + (active? ' active': '')}> text </div> </div> const component = React.createClass({ getInitialState() { return {active: false} }, toggle() { this.setState({active: !this.state.active}) }, render() { return collapsible({active: this.state.active, toggle: this.toggle}) } }) ReactDOM.render(React.createElement(component), document.querySelector('#root'))
.collapsible { height: 1.5rem; transition: height 0.25s linear; background: #333; border-radius: 0.25rem } .collapsible.active { height: 7rem }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script> <div id="root"></div>
CSS轉換可以平滑地“縮小”或“展開”視圖,這是通過更改CSS屬性觸發的。
要使用React控制CSS屬性,我們可以在render()
反映屬性值或className
狀態更改。
在此示例中, .active
類影響height
值,並由state.active
控制。 響應狀態更改,React切換該類,並觸發CSS轉換。
要獲得更平滑的過渡,請參閱此文章 。
標准方法是使用react-transition-group中的 CSSTransitionGroup,這非常簡單。 使用CSSTransitionGroup
包裝組件並在進入和離開時設置超時,如下所示:
<CSSTransitionGroup
transitionName="example"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}>
{items}
</CSSTransitionGroup>
來自v1-stable文檔 :
“在這個組件中,當一個新項目被添加到CSSTransitionGroup時,它將獲得示例 - 輸入CSS類,並在下一個tick中添加example-enter-active CSS類。”
為CSS類添加樣式以獲取正確的動畫。
在React docs中也有很好的解釋,請查看。
還有動畫的第三方組件。
這種情況的另一種方法可能是在動畫完成后改變狀態。 它的好處是你不僅可以應用轉換,而且可以應用你想要的任何動作(js動畫,smil等等),主要的是不要忘記調用結束回調;)
這是CodePen的工作示例
這是代碼示例:
const runTransition = (node, {property = 'opacity', from, to, duration = 600, post = ''}, end) => {
const dif = to - from;
const start = Date.now();
const animate = ()=>{
const step = Date.now() - start;
if (step >= duration) {
node.style[property] = to + post;
return typeof end == 'function' && end();
}
const val =from + (dif * (step/duration));
node.style[property] = val + post;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}
class Comp extends React.Component {
constructor(props) {
super(props);
this.state = {
isCollapsed: false
}
this.onclick = (e)=>{
this.hide(e.currentTarget,()=>{
this.setState({isCollapsed: !this.state.isCollapsed})
});
};
this.refF = (n)=>{
n && this.show(n);
};
}
render() {
if (this.state.isCollapsed){
return this.renderCollapsed();
}
return this.renderActive()
}
renderCollapsed() {
return (
<div
key='b'
style={{opacity: 0}}
ref={this.refF}
className={`b`}
onClick={this.onclick}>
<h2>I'm Collapsed</h2>
</div>
)
}
renderActive() {
return (
<div
key='a'
style={{opacity: 0}}
ref={this.refF}
className={`a`}
onClick={this.onclick}>
<h2>I'm Active</h2>
</div>
)
}
show(node, cb) {
runTransition(node, {from: 0, to: 1}, cb);
}
hide(node, cb) {
runTransition(node, {from: 1, to: 0}, cb);
}
}
ReactDOM.render(<Comp />, document.getElementById('content'));
當然,對於這種工作方法,你唯一的機會是繼續使用狀態,而不是Component的道具,如果你必須處理它們,你可以隨時在componentWillReceiveProps方法中設置它。
使用更清晰的示例更新了Codepen鏈接 ,該示例顯示了此方法的優點。 轉換更改為javascript動畫,而不依賴於transitionend事件。
您可以添加描述活動狀態的類,即。 .active
並在切換狀態時切換該類。
css看起來應該是這樣的:
.your-component-name{
// inactive css styling here
}
.your-component-name.active {
// active css styling here
}
由於您想為每個活動和折疊渲染兩個不同的組件,請將它們包裝在一個div中,該div通過CSS幫助控制高度。
render: function(){
var cls = this.props.isCollapsed() ? 'collapsed' : 'expanded';
return(
<div className={cls + ' wrapper'}>
{
this.props.isCollapsed() ?
this.renderCollapsed() :
this.renderActive()
}
</div>
);
}
在你的CSS中:
.wrapper{
transition: transform .5s linear;
}
.expanded{
height: 200px;
}
.collapsed{
height: 20px;
}
在這里你有一個使用Velocity-React庫的Toggle反應組件,它非常適合為React uis中的過渡提供動畫:
import React, { Component } from 'react';
import { VelocityTransitionGroup } from 'velocity-react';
export default class ToggleContainer extends Component {
constructor () {
super();
this.renderContent = this.renderContent.bind(this);
}
renderContent () {
if (this.props.show) {
return (
<div className="toggle-container-container">
{this.props.children}
</div>
);
}
return null
}
render () {
return (
<div>
<h2 className="toggle-container-title" onClick={this.props.toggle}>{this.props.title}</h2>
<VelocityTransitionGroup component="div" enter="slideDown" leave="slideUp">
{this.renderContent()}
</VelocityTransitionGroup>
</div>
);
}
};
ToggleContainer.propTypes = {
show: React.PropTypes.bool,
title: React.PropTypes.string.isRequired,
toggle: React.PropTypes.func.isRequired,
};
希望能幫助到你!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.