React-router 动画问题

#1

使用react-transition-group 来做路由动画。放在单个组件中可以使用。但是在路由中没有效果。请教一下是怎么解决?

import React from 'react';
import {Link} from 'react-router';
import {CSSTransitionGroup} from 'react-transition-group' ;
import './main.css'
let styles = {
  leftNav: {
    width: '170px',
    position: 'fixed',
    top: '56px',
    height: '100%',
    background: 'lightblue'
  },
  content: {
    background: '#fff',
    position: 'absolute',
    top: '56px',
    left: '200px',
    width: '70%',
    height: '90%',
  },
  menu: {
    display: 'block',
    overflow: 'hidden'
  },
  list: {
    fontSize: "20px",
    listStyle: "none",
  },
  reset: {
    textDecoration: "none"
  }
}
let leftNav = () => {
  return (
    <nav>
      <ul>
        <li style={styles.list}><Link activeStyle={{color: 'red'}} style={styles.reset} to="/com1">one</Link></li>
        <li style={styles.list}><Link activeStyle={{color: 'red'}} style={styles.reset} to="/com2">two</Link></li>
        <li style={styles.list}><Link activeStyle={{color: 'red'}} style={styles.reset} to="/com3">three</Link></li>
        <li style={styles.list}><Link activeStyle={{color: 'red'}} style={styles.reset} to="/todo">todo</Link></li>
      </ul>
    </nav>
  )
}
class App extends React.Component {
  render() {
    return (
      <div>
        <div className="leftNav" style={styles.leftNav}>
          {leftNav()}
        </div>
        <div className="content" style={styles.content}>
          <CSSTransitionGroup
            transitionName="a"
            transitionEnterTimeout={500}
            transitionLeaveTimeout={300}>
            <div style={{position:"relative",width:"100%"}}>
              {this.props.children}
            </div>
          </CSSTransitionGroup>
        </div>
      </div>
    );
  }
}
export default App;
css


.a-enter {
    opacity: 0.01;
    color:yellow;
}
.a-enter.a-enter-active {
    opacity: 1;
    transition: opacity 500ms ease-in;
    color: red;
}
.a-leave {
    opacity: 1;
}
.a-leave.a-leave-active {
    opacity: 0.01;
    transition: opacity 300ms ease-in;
}



版本
“react”: “^15.6.1”,
“react-dom”: “^15.6.1”,
“react-router”: “^3.0.5”,
“react-transition-group”: “^1.2.0”,

CSSTransitionGroup 是放在父组件里呢还是应写在react-router 的config中?

#2

恐怕你没看清楚文档,根元素需要一个key。

<div key={this.props.location.pathname} style={{position:"relative",width:"100%"}}>
1 Like
#3

需要给使用过度的元素添加一个唯一的key,用来区分进入,离开时过度动画的元素

1 Like
#4

但是我加上了key 依旧不可以

import './Components/main.css'
class App extends React.Component {
  render() {
    return (
      <Router>
        <div>
          <div className="leftNav" style={styles.leftNav}>
            {leftNav()}
          </div>
          <div className="content" style={styles.content}>
            <CSSTransitionGroup
              transitionName="a"
              transitionEnter={true}
              transitionLeave={true}
              transitionEnterTimeout={500}
              transitionLeaveTimeout={300}>
              <div key={location.pathname}>
                <Route exact path="/" component={Com1}/>
                <Route exact path="/com1" component={Com1}/>
                <Route exact path="/com2" component={Com2}/>
                <Route exact path="/com3" component={Com3}/>
                <Route exact path="/todo" component={TodoList}/>
              </div>
            </CSSTransitionGroup>
          </div>
        </div>
      </Router>
    );
  }
}
let root = document.getElementById('app');
render(<App/>, root);

css 确定已经引入成功

#5

在render打印location.pathname的值看看

#6

#7

ok,把动画时间设置成100000秒,检查浏览器的dom脚本,如果看到你的a类添加到dom上面,说明是执行了动画class,只是你的动画可能写错了。

#8

没有写错,同样的动画我放在其他地方就可以执行,比如

 aa() {
    var list = []
    this.state.list ? this.state.list.map((item, i) => {
      list.push(
        <div key={i} onClick={() => {
          this.move(i)
        }}>{item}</div>
      )
    }) : ''
    return list;
  }



  render() {
    var kk = new Date().getTime();
    return (
      <BrowserRouter>
        <div>
          <div className="leftNav" style={styles.leftNav}>
            {leftNav()}
          </div>
          <div className="content" style={styles.content}>
            <CSSTransitionGroup
              transitionName="a"
              transitionEnterTimeout={500}
              transitionLeaveTimeout={300}>
              <div key={location.pathname} style={{position:"relative"}}>
                <Route exact path="/" component={Com1}/>
                <Route exact path="/com1" component={Com1}/>
                <Route exact path="/com2" component={Com2}/>
                <Route exact path="/todo" component={TodoList}/>
                <Route exact path="/com3" component={Com3}/>
              </div>
            </CSSTransitionGroup>
            {/*这个动画是可以执行的*/}
            <CSSTransitionGroup
              transitionName="a"
              transitionEnterTimeout={500}
              transitionLeaveTimeout={300}>
              {this.aa()}
            </CSSTransitionGroup>
          </div>
        </div>
      </BrowserRouter>
    );
  }

同样的代码,放到路由当中怎么就不好使呢

#9

外面多加一层路由就可以了,但是为什么?不知道

<BrowserRouter>
        <Route render={({location}) => (  // 为何必须加这一步
          <div>
            <div className="leftNav" style={styles.leftNav}>
              {leftNav()}
            </div>
            <div className="content" style={styles.content}>
              <CSSTransitionGroup
                transitionName="a"
                transitionEnterTimeout={500}
                transitionLeaveTimeout={300}>
                <div key={Math.random()} data-key={location.pathname} style={{position: "relative"}}>
                  <Route exact path="/" component={Com1}/>
                  <Route exact path="/com1" component={Com1}/>
                  <Route exact path="/com2" component={Com2}/>
                  <Route exact path="/todo" component={TodoList}/>
                  <Route exact path="/com3" component={Com3}/>
                </div>
              </CSSTransitionGroup>
              {/*这个动画是可以执行的*/}
              {/*<CSSTransitionGroup*/}
              {/*transitionName="example"*/}
              {/*transitionEnterTimeout={500}*/}
              {/*transitionLeaveTimeout={300}>*/}
              {/*{this.aa()}*/}
              {/*</CSSTransitionGroup>*/}
            </div>
          </div>
        )}/>
      </BrowserRouter>