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的更新解决方案

Edit 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;
}

以上是关于React Router v4动画转换示例的主要内容,如果未能解决你的问题,请参考以下文章

React-router-dom (v6) 和 Framer Motion (v4)

使用 React Router v4 正确重定向

react-router v4 学习实践

在 react-router v4 中使用 React IndexRoute

具有多种布局的 React Router v4

如何在React Router v4中获取所有参数