即使设置了密钥,React CSSTransitionGroup也不起作用

时间:2017-08-25 13:34:59

标签: javascript reactjs

我从昨天开始一直在尝试为我的图像轮播制作动画。据我所知,您使用CSSTransitionGroup包装要动画的内容,并确保它保留在dom中,并为转换组的每个子项指定唯一键。我相信我已经遵循了这一切,但我认为没有过渡。

值得一提的是,当我试图让这个工作时,我怀疑如果键有问题,所以我尝试用随机字符串设置键。密钥会随着状态的变化而改变,由于某种未知的原因,我可以看到动画。谁可以给我解释一下这个。

我不确定我哪里出错,无论是转型组的版本还是设置儿童的钥匙,都没有线索!

以下是复制我的问题的代码。

var CSSTransitionGroup = React.addons.CSSTransitionGroup


class Images extends React.Component {
    constructor(props){
    super(props);
    this.state = {
        showComponent: false,
    }
  }

  componentWillReceiveProps(nextProps){
    if (this.props.name === nextProps.showComponentName){
        this.setState({
        showComponent: true,
      })
    } else {
      this.setState({
        showComponent: false,
      })
    }
  }

  render() {
    if (this.state.showComponent){
        return (
        <img src={this.props.url} />
      )
    } else {
        return null;
    }
  }
}


class TransitionExample extends React.Component {

  constructor (props) {
    super(props);
    this.onClick = this.onClick.bind(this);
    this.state= {
        showComponentName: null,
    }
  }

    onClick(button) {
    this.setState({
        showComponentName: button.currentTarget.textContent,
    })
  }

    render() {
        var imageData = [
        "http://lorempixel.com/output/technics-q-c-640-480-9.jpg",
            "http://lorempixel.com/output/food-q-c-640-480-8.jpg",
            "http://lorempixel.com/output/city-q-c-640-480-9.jpg",
            "http://lorempixel.com/output/animals-q-c-640-480-3.jpg"
    ];

        var images = [];
        for (var i in imageData) {
            i = parseInt(i, 10);
            images.push(
                <Images url={imageData[i]} showComponentName={this.state.showComponentName} name={imageData[i]} key={imageData[i]} />
            );
        }

    return (
        <div>
        <div>
        <button onClick={this.onClick}>{imageData[0]}</button>
        <button onClick={this.onClick}>{imageData[1]}</button>
        <button onClick={this.onClick}>{imageData[2]}</button>
        <button onClick={this.onClick}>{imageData[3]}</button>
      </div>
        <div className="transitions">
        <CSSTransitionGroup
            transitionName="viewphoto"
          transitionEnterTimeout={2000}
          transitionLeaveTimeout={2000}
          transitionAppearTimeout={2000}
          transitionAppear={true}
          transitionEnter={true}
          transitionLeave={true}>
                        {images}
        </CSSTransitionGroup>
            </div>
      </div>
    );
    }
}


ReactDOM.render(
  <TransitionExample />,
  document.getElementById('container')
);

我还提供了jsfiddle

上示例的链接

1 个答案:

答案 0 :(得分:1)

您的代码存在的问题是images始终是一组不能挂载/卸载的元素。正确的方法是改变孩子。例如,如果用这个替换你的小提琴的render方法的返回:

return (
    <div>
    <div>
    <button onClick={this.onClick}>{imageData[0]}</button>
    <button onClick={this.onClick}>{imageData[1]}</button>
    <button onClick={this.onClick}>{imageData[2]}</button>
    <button onClick={this.onClick}>{imageData[3]}</button>
  </div>
    <div className="transitions">
    <CSSTransitionGroup
        transitionName="viewphoto"
      transitionEnterTimeout={2000}
      transitionLeaveTimeout={2000}
      transitionAppearTimeout={2000}
      transitionAppear={true}
      transitionEnter={true}
      transitionLeave={true}>
          <img src={this.state.showComponentName} key={this.state.showComponentName}/>
    </CSSTransitionGroup>
        </div>
  </div>
);

动画有效!使用简单的img代替您的Images组件并为其提供图片网址(仅当您点击按钮时才有效,showComponentName应初始化以显示第一张图片)。您当然也可以使用自定义组件,但这里的要点是如果您想要触发动画,则必须更改CSSTransitionGroup的子元素,否则您总是渲染相同的四个Images组件无论他们是否返回i​​mg 。您可能需要查看react-css-transition-replace,因为它在更换时通常会更好。