Пример анимированного перехода React Router v4

Пример перехода с анимацией, приведенный в документации v4, кажется немного запутанным для меня, так как он изображает появление и исчезновение одного и того же компонента и настройку цвета фона.

Я пытаюсь применить эту технику к более реальному примеру постепенного исчезновения одного компонента и появления другого, однако я не могу заставить его работать должным образом (кажется, что первый исчезает, а затем появляется второй). 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;

Я понимаю, что этот вопрос почти дублирует этот , однако у него есть принятый ответ, который на самом деле не отвечает на вопрос.


person dougmacklin    schedule 20.12.2016    source источник
comment
Я не особо знаком с react-motion, но похоже, что у <TransitionMotion> есть реквизит willEnter. Вы пробовали это использовать?   -  person Paul S    schedule 21.12.2016
comment
Просто дикая догадка: у вас установлена ​​фиксированная/абсолютная позиция?   -  person ps-aux    schedule 29.11.2017
comment
Я тоже не слишком хорошо знаком с react-motion, но, глядя на ваш код, мне интересно, связано ли это с z-индексом, который вы пытаетесь перевести. Ваши стили по умолчанию для компонента TransitionMotion не имеют z-индекса, так что это может мешать переходу. Попробуйте заменить эту строку чем-то вроде: style: { zIndex: 2, opacity: spring(1) } -- я не знаю, нужен ли бит spring? Но вы можете попробовать обернуть туда и свои z-индексы.   -  person Jonny Asmar    schedule 23.12.2017
comment
Первая ссылка мертва. Какое демо вы имеете в виду?   -  person newguy    schedule 26.12.2017
comment
@newguy похоже, что домен для их документов изменился, я пошел дальше и обновил ссылку, так что теперь она должна работать. Однако я задал этот вопрос более года назад, поэтому вполне вероятно, что другие вещи также устарели.   -  person dougmacklin    schedule 26.12.2017


Ответы (4)


react-motion не подходит для больших приложений. Вместо этого используйте react-transition-group.

Потому что react-motion используют javascript для выполнения перехода. При вызове API переход будет пересекаться (вызов синхронизации в js) и сделает переход медленным при переходе на новую страницу. Где в качестве react-transition-group используйте CSS для выполнения перехода.

person Ibrahim    schedule 12.09.2018

документы v4 перемещены в react-transition-group, так что вы можете рассмотреть возможность выполнения такой же.

Что касается «исчезновения и появления одного и того же компонента», на самом деле это не один и тот же экземпляр компонента. Два экземпляра существуют одновременно и могут обеспечить плавное затухание. react-motion docs говорит, что "TransitionMotion держал c рядом", и я полагаю, что react-transition-group является такой же.

person Jayen    schedule 25.12.2017
comment
Спасибо @Jayen, это имеет смысл. Я задал этот вопрос более года назад, поэтому он, скорее всего, очень устарел. Лично я больше не ищу решение этой проблемы, однако я оставляю его открытым, так как он по-прежнему получает приличный объем трафика, что наводит меня на мысль, что другие также ищут лучший пример, чем в документации. - person dougmacklin; 26.12.2017

Вот обновленное решение с использованием реакции 16 и ReactCSSTransitionGroup из группы «реагировать-аддоны-css-transition-group».

  Изменить zw0xv4vy3x

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;
}
person Radu Luncasu    schedule 12.04.2018
comment
Спасибо за ваше представление, однако я не понимаю, как это связано с анимацией перехода между маршрутами с помощью react-router. Я задал этот вопрос более года назад, поэтому он, скорее всего, очень устарел. Лично я больше не ищу решение этой проблемы, однако я оставляю его открытым, так как он по-прежнему получает приличный объем трафика, что наводит меня на мысль, что другие также ищут лучший пример, чем в документации. - person dougmacklin; 13.04.2018

Мне тоже не понравился пример RRv4 с анимацией. В итоге я написал свой собственный AnimatedSwitch для RRv4 Native.

Я полагаю, что не потребуется слишком много усилий, чтобы заменить родные анимации на реактивную пружину и запустить ее.

https://javascriptrambling.blogspot.com/2020/07/react-router-native-animatedswitch.html

person Kevin Williams    schedule 20.08.2020