我有一个类似调查的 React 应用程序,它使用各种 UI 组件将各种问题呈现到屏幕上。
但是,调查的性质是许多问题使用完全相同的组件重新呈现。例如,“A/B 选择器”或“清单”。
我想要实现的是每个组件,无论它是被重新使用还是第一次安装到 DOM,都从底部淡出 - 一旦用户选择答案,就会淡出。
这是一个使用五个问题和一个小方框的非常基本的示例:
import React, {Component, PropTypes} from 'react';
import ReactDOM from 'react-dom';
import { observer, Provider, inject } from 'mobx-react';
import { observable, computed, action } from 'mobx';
import 'gsap';
import TransitionGroup from 'react-addons-transition-group';
// STORE
class APP_STORE {
@observable showingBox = true;
@observable transDuration = .25;
@observable questionIndex = 0;
@observable questions = [
{text: 'one'},
{text: 'two'},
{text: 'three'},
{text: 'four'},
{text: 'five'},
];
@computed get currentQuestion() {
return this.questions[this.questionIndex];
}
@action testTrans () {
this.showingBox = !this.showingBox;
setTimeout(() => {
this.questionIndex++;
this.showingBox = !this.showingBox;
}, this.transDuration * 1000);
}
}
let appStore = new APP_STORE();
// TRANSITION w/HIGHER ORDER COMPONENT
function fadesUpAndDown (Component) {
return (
class FadesUp extends React.Component {
componentWillAppear (callback) {
const el = ReactDOM.findDOMNode(this);
TweenMax.fromTo(el, appStore.transDuration, {y: 100, opacity: 0}, {y: Math.random() * -100, opacity: 1, onComplete: callback});
}
componentWillEnter (callback) {
const el = ReactDOM.findDOMNode(this);
TweenMax.fromTo(el, appStore.transDuration, {y: 100, opacity: 0}, {y: Math.random() * -100, opacity: 1, onComplete: callback});
}
componentWillLeave (callback) {
const el = ReactDOM.findDOMNode(this);
TweenMax.to(el, appStore.transDuration, {y: 100, opacity: 0, onComplete: callback});
}
render () {
return <Component ref="child" {...this.props} />;
}
}
)
}
// REACT
@fadesUpAndDown
class Box extends React.Component {
render () {
return <div className="box" ref={c => this.container = c}> {this.props.data.text} </div>;
}
}
@inject('store') @observer
class Page extends Component {
render () {
const store = this.props.store;
return (
<div className="page">
<TransitionGroup>
{ store.showingBox ? <Box data={store.currentQuestion}/> : null }
</TransitionGroup>
<button className="toggle-btn" onClick={() => { store.testTrans(); } } >
test trans
</button>
</div>
);
}
}
这行得通!但是...要完成它,我必须手动从 DOM 中删除 box 组件(在本例中是通过showingBox
observable),为过渡持续时间设置超时,然后完全重新安装组件。
最终我想这很好,但我想知道 SO 社区中是否有人遇到过类似的情况,并且有更好的解决方法,因为卸载/重新安装并不是非常强大的 React。