React Router v4和React Transition Group v2

时间:2017-09-01 13:26:52

标签: reactjs react-router react-redux react-transition-group

我正在尝试使用具有React Transition Group v2的React Router v4找到低级动画的工作示例。我查看了React Router文档中的示例,但他们只使用一个路径的CSS Animation。

这就是我目前使用React路由器的方式:

export const App = () => (
  <div className="app-container">
    <main className="app-container__content">
      <Switch>
        <Route exact path="/projects/:slug" component={ProjectPage} />
        <Route exact path="/" component={StartPage} />
      </Switch>
    </main>
  </div>
);

这是我的Root.jsx:

const Root = ({ store, history }) => (
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Switch>
        <Route path="/" component={App} />
      </Switch>
    </ConnectedRouter>
  </Provider>
);

我在这里测试了解决方案:https://hackernoon.com/animated-page-transitions-with-react-router-4-reacttransitiongroup-and-animated-1ca17bd97a1a - 但它不起作用。有人能指出我正确的方向吗?

更新

我试过这样,但回调没有被调用。所以我最终得到了dom中的页面。

export const App = ({ location }) => {
  console.log(location);

  return (
    <div className="app-container">
      <main className="app-container__content">
        <ScrollToTop />
        <TransitionGroup>
          <Switch key={location.pathname} location={location}>
            <Route exact path="/projects/:slug" component={ProjectPage} />
            <Route exact path="/" component={StartPage} />
          </Switch>
        </TransitionGroup>
      </main>
    </div>
  );
};

2 个答案:

答案 0 :(得分:0)

您错过了Transition组件本身

看起来应该是这样的:

<TransitionGroup>
  <CSSTransition
    key={location.key}
    classNames="page-animation"
    timeout={{ enter: PAGE_ENTER_ANIMATION_SPEED, exit: PAGE_EXIT_ANIMATION_SPEED }}>
    <Switch location={location}>
      <Route exact path="/projects/:slug" component={ProjectPage} />
      <Route exact path="/" component={StartPage} />
    </Switch>
  </CSSTransition>
</TransitionGroup>

请注意,密钥位于CSSTransition本身,而不是Switch

更新

如果您想自己实施它 这是CSSTransition

的基本实现
class MyTransition extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            inTransition: true,
            playAnimation: false,
        };
    }

    componentDidMount() {
        setTimeout(() => {
            this.setState({playAnimation: true});
        }, 1);

        this.removeClassesAndFireOnExited();
    }

    removeClassesAndFireOnExited() {
        setTimeout(() => {
            this.setState({playAnimation: false, inTransition: false}, () => {
                if (!this.props.in) {
                    this.props.onExited(this);
                }
            });
        }, this.props.timeout[this.props.in ? 'enter' : 'exit']);
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.in !== this.props.in) {
            this.setState({inTransition: true});
            setTimeout(() => {
                this.setState({playAnimation: true});
            }, 1);

            this.removeClassesAndFireOnExited();
        }
    }

    render() {
        const baseClassName = this.props.in ? 'page-animation-enter' : 'page-animation-exit';
        const {inTransition, playAnimation} = this.state;

        const transitionClasses = [...(inTransition ? [baseClassName] : []), ...(playAnimation ? [baseClassName + '-active'] : [])];

        return (
            <div className={transitionClasses.join(' ')}>
                {this.props.children}
            </div>
        );
    }
}

您从this.props.in获得TransitionGroup来表明您是进入还是离开 this.props.onExited是您从TransitionGroup获得的另一个道具,您必须在退出动画完成时调用它,因此TransitionGroup将知道您应该卸载。

答案 1 :(得分:0)

这篇文章解释了如何设置react-router v4和react-transition-group与多个路由以及根据下一个状态的转换:https://medium.com/lalilo/dynamic-transitions-with-react-router-and-react-transition-group-69ab795815c9