Reaguj, płynnie przechodząc między różnymi stanami w komponencie


Mam taki prosty element:
<pre class="lang-js prettyprint-override">
var component = React.createClass({
render: function(){
if (this.props.isCollapsed){
return this.renderCollapsed();
}
return this.renderActive()
},
renderActive: function(){
return ( <div>
...

);
},
renderCollapsed: function(){
return ( <div>
...

);
},
});

Zasadniczo, gdy właściwość ulegnie zmianie, komponent pokaże stan aktywny lub zwinie się.
Zastanawiam się, kiedy następuje zmiana właściwości, np. Aktywny- & > zwijanie lub odwrotnie, chcę, aby stary widok „zmniejszania” lub „rozszerzania” płynnie wyświetlał nowy widok. Na przykład, jeśli jest aktywny - & > zwiń, chcę, aby aktywny interfejs użytkownika zmniejszył się, aby zwinąć rozmiar interfejsu użytkownika i wyświetlić go płynnie.
Nie wiem, jak osiągnąć taki efekt. Podziel się kilkoma pomysłami. Podziękować!
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Zamiast

warunkowe wyświetlanie dwóch różnych stanów końcowych
komponent, możesz

przełącz klasę

za to samo
składnik. Możesz mieć aktywne i zwinięte klasy w ten sposób:


Na przykład:
.active{
-webkit-transition: -webkit-transform .5s linear;// transition of
// 0.5 of a second
height: 200px;
}.collapsed{
height: 0px;
}

Sprawdzić

ten zasób
https://css-tricks.com/almanac ... tion/
dla przykładów
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oto minimalny działający przykład:
<div class="snippet-code">
<div class="snippet" data-babel="true" data-console="true" data-hide="false" data-lang="js">
<pre class="snippet-code-js lang-js prettyprint-override">
const collapsible = ({active, toggle}) =>
<div>
<button type="button" onClick={toggle}>Toggle</button>
<div className={'collapsible' + (active? ' active': '')}>
text
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'))

<pre class="snippet-code-css lang-css prettyprint-override">
.collapsible {
height: 1.5rem;
transition: height 0.25s linear;
background: #333;
border-radius: 0.25rem
}.collapsible.active {
height: 7rem
}

<pre class="snippet-code-html lang-html prettyprint-override">
<script src="[url=https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>]https://cdnjs.cloudflare.com/a ... gt%3B[/url]
<script src="[url=https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>]https://cdnjs.cloudflare.com/a ... gt%3B[/url]
<div id="root">

Widok można płynnie „zmniejszać” lub „rozszerzać”

przejście
https://developer.mozilla.org/ ... ition
CSS, który jest uruchamiany przez zmianę właściwości CSS.
Aby manipulować właściwościami CSS za pomocą Reacta, możemy odzwierciedlić zmiany stanu w wartościach właściwości lub
className
w
render ()
.
W tym przykładzie klasa
.active
wpływa na wartość
height
i jest kontrolowana przez
state.active
. Klasa przełącza React w odpowiedzi na zmiany stanu i wyzwala przejście CSS.
Aby uzyskać płynniejsze przejścia, zobacz B.

Ten artykuł
https://medium.com/outsystems- ... bkn8a
.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Standardowym sposobem jest użycie CSSTransitionGroup from

react-transition-group
https://github.com/reactjs/react-transition-group/
co jest całkiem proste. Owiń komponent tagiem
CSSTransitionGroup
i ustaw limity czasu wejścia i wyjścia, na przykład:
<CSSTransitionGroup
transitionName="example"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}>
{items}
</CSSTransitionGroup>

Z

Dokumentacja stabilna v1
https://github.com/reactjs/rea ... table
:

„W tym komponencie, kiedy nowy element jest dodawany do CSSTransitionGroup, to
otrzyma przykładową klasę CSS i przykładową enter-aktywną klasę CSS
klasa zostanie dodana w następnym tiku. "

Stylizuj swoje klasy CSS, aby uzyskać odpowiednią animację.
Jest też całkiem dobre wyjaśnienie

React docs
https://facebook.github.io/rea ... .html, Sprawdź to.
Istnieją również komponenty animacji innych firm.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Innym podejściem do tej sytuacji byłaby zmiana stanu po zakończeniu animacji. Jego zaletą jest to, że możesz zastosować nie tylko przejścia, ale także dowolne akcje (animacje JS, uśmiech itp.), Najważniejsze to nie zapomnieć o wywołaniu callback;)
Oto działający przykład

CodePen
http://codepen.io/pwroff/pen/JEXKJe
A oto przykładowy kod:
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}>
[b]I'm Collapsed[/b]>

)
} renderActive() {
return ( <div
key='a'
style={{opacity: 0}}
ref={this.refF}
className={`a`}
onClick={this.onclick}>
[b]I'm Active[/b]>

)
} 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'));

Oczywiście, aby to podejście zadziałało, jedyną opcją jest przekazanie stanu, a nie właściwości komponentów, które zawsze możesz ustawić w metodzie componentWillReceiveProps, jeśli masz z nimi do czynienia.

Zaktualizowano
>
Link Codepen
http://codepen.io/pwroff/pen/xggXVB
zaktualizowany o jaśniejszy przykład, który pokazuje korzyści płynące z tego podejścia. Przejście zostało zmienione na animację JavaScript bez polegania na zdarzeniu przejścia.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz dodać klasę opisującą stan aktywny, tj.
.active
i przełączać tę klasę podczas przełączania stanów.
css powinien wyglądać mniej więcej tak:
.your-component-name{
// inactive css styling here
}.your-component-name.active {
// active css styling here
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ponieważ chcesz renderować dwa różne komponenty dla każdego aktywnego i zwiniętego, zawiń je w element div, który kontroluje wysokość za pomocą CSS.
<pre class="lang-js prettyprint-override">
render: function(){
var cls = this.props.isCollapsed() ? 'collapsed' : 'expanded';
return( <div className={cls + ' wrapper'}>
{
this.props.isCollapsed() ?
this.renderCollapsed() :
this.renderActive()
}
);
}

aw swoim CSS:
.wrapper{
transition: transform .5s linear;
}.expanded{
height: 200px;
}.collapsed{
height: 20px;
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Tutaj masz komponent Toggle React wykorzystujący bibliotekę Velocity-React, który świetnie nadaje się do tworzenia animacji przejść w interfejsach React:
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}

);
}
return null
} render () {
return ( <div>
<h2 className="toggle-container-title" onClick={this.props.toggle}>{this.props.title}[/b]>
<VelocityTransitionGroup component="div" enter="slideDown" leave="slideUp">
{this.renderContent()}
</VelocityTransitionGroup>

);
}};ToggleContainer.propTypes = {
show: React.PropTypes.bool,
title: React.PropTypes.string.isRequired,
toggle: React.PropTypes.func.isRequired,
};

Mam nadzieję że to pomoże!

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się