12

我正在尝试通过单击按钮做出简单的转换,其中在 componentWill 更新时 body max-height 变为 0,然后在 componentDidUpdate 上返回 500px 或 100%。我还没有从我看到的其他问题中完全理解它,所以有人可以给我一个例子来解释它是如何工作的吗?

我也不介意使用 reactcsstransitiongroup 的示例/解释。

更多信息

我知道 transitionend 附加了一个事件侦听器,但我感到困惑的是如何使用它来确保组件在转换完成之前不会更新(我已经自学了反应和几乎所有的编码知识,所以我不知道这是否应该很难理解,但目前对我来说很难)。谢谢大家!

4

1 回答 1

11

所以在休息了一段时间后,我决定是时候再写一章“学生教学生”(由我执导并主演)。

为了更简洁地回答我自己的问题,transitionend 事件侦听器将侦听器附加到元素,并在转换结束时触发回调函数。我遇到的问题是这是异步的,因此将其放入 componentWillUpdate 将不起作用,因为 DOM 会在转换完成之前呈现。我目前的解决方法是让按钮单击调用包含事件侦听器的函数,并让 trnasitionend 的回调函数更改组件的状态。这样,在过渡完成之前不会进行渲染。

代码:

class Button2 extends React.Component {
  constructor(props){
    super(props)
    this.onClickHandler = this.onClickHandler.bind(this)
  }

  onClickHandler(){
    this.props.onClick("Button2")
  }

  render() {
    return (
        <button onClick={this.onClickHandler} id="button2">
            BUTTON2!!
        </button>
    )



 }
}

class Button1 extends React.Component {

  constructor(props){
    super(props)
    this.onClickHandler = this.onClickHandler.bind(this)
  }

  onClickHandler(){
    this.props.onClick('Button1')
  }

  render() {
    return (
        <button onClick={this.onClickHandler} id="button1">
            BUTTON1!!
        </button>
    )
  }
}

class App extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      showButton : true,
      hide: false
    }
    this.changeButtonState = this.changeButtonState.bind(this)
    this.getButton = this.getButton.bind(this)
    this.transitionEndEventName = this.transitionEndEventName.bind(this)
    this.hideApp = this.hideApp.bind(this)
    this.removeEvent = this.removeEvent.bind(this)
  }

  getButton() {
    if (this.state.showButton){
        return <Button1 onClick={this.hideApp}/>
      } else {
        return <Button2 onClick={this.hideApp}/>
      }
  }

  transitionEndEventName () {
    var el = document.createElement('div')//what the hack is bootstrap

    var transEndEventNames = {
      WebkitTransition : 'webkitTransitionEnd',
      MozTransition    : 'transitionend',
      OTransition      : 'oTransitionEnd otransitionend',
      transition       : 'transitionend'
    }

    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return transEndEventNames[name];
      }
    }

    return false // explicit for ie8 (  ._.)
}


  hideApp(button) {
    var app = document.getElementById('main')
    var transitionEnd = this.transitionEndEventName()
    app.addEventListener(transitionEnd, this.removeEvent, false)
        app.classList.contains('show-element') ? app.classList.remove('show-element') : null
        app.classList.add('remove-element')
  }

  removeEvent(){
    console.log('hey')
    var app = document.getElementById('main')
    var transitionEnd = this.transitionEndEventName()
    app.removeEventListener(transitionEnd, this.removeEvent, false)
    this.changeButtonState()
  }

  changeButtonState(button) {
    this.setState({
      showButton: !this.state.showButton,
      hide: true
    })
  }

  componentDidUpdate(){
    var app = document.getElementById('main')
    app.classList.contains('remove-element') ? app.classList.remove('remove-element') : null
    app.classList.add('show-element')
  }

  render(){
    var button = this.getButton()
    return (
        <div id="button-container">
            {button}
        </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('main'))

代码笔(检查代码笔

于 2017-09-06T03:49:35.927 回答