简体   繁体   English

我在重新渲染时隐藏的反应组件上的动画过渡

[英]Animate transition on a react component that i hide on re-render

im using reactjs and i have a datepicker component that i hide when the user clicks outside of the component element.我正在使用 reactjs 并且我有一个 datepicker 组件,当用户在组件元素外部单击时我会隐藏该组件。

the code snippet is like so:代码片段是这样的:

`
class DatePicker extends Component{
   constructor(props){
      super(props)
      state= { focus: false }  // when focus: false i hide the dates component 
  }    
  .......
  render(){
    const { focus } = this.state

    return(
      <input type="text" placeholder="start date">
      <input type="text" placeholder="start date">
      {focus &&  <DatesContainer ...props>} // if focus==false i dont show the <DatesContainer> component.I need to hide it with fade out or something.
    )
  }
}`

So when the user clicks outside of the <DatesContainer/> the state.focus updates to false, the re-renders and, this time, the <DatesContainer/> is not render at all, so far so good.因此,当用户在<DatesContainer/>之外单击时 state.focus 更新为 false,重新渲染,而这一次, <DatesContainer/>根本没有渲染,到目前为止一切都很好。 But i need to hide it with a 0.3s animation.但我需要用 0.3 秒的动画隐藏它。

Any opinions on that ?对此有何意见?

I'd update the state to have a transitioning property.我会更新状态以具有transitioning属性。 Using CSS animations or transitions, and some conditional rendering, we can apply a new class to the DatesContainer, detect when an animation is finished and change the focus state to false.使用 CSS 动画或转换以及一些条件渲染,我们可以将一个新类应用于 DatesContainer,检测动画何时完成并将焦点状态更改为 false。

You'll have to set transitioning to true in the state whenever you click outside it.每当您在状态外单击时,您都必须在状态中将转换设置为 true。

It may look something like this:它可能看起来像这样:

CSS CSS

@keyframes fadeOut {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}

.fading {
    animation-name: fadeOut;
    animation-duration: 0.3s;
    animation-fill-mode: forwards;
    will-change: opacity;
}

JS JS

//import your styles here

class DatePicker extends Component{
   constructor(props){
      super(props)
      state= { focus: false, transitioning: false }
  }    

  handleFade() {
    this.setState({transitioning: false})
  }

  render(){
    const { focus, transitioning } = this.state

    return(
      <input type="text" placeholder="start date">
      <input type="text" placeholder="start date">
      {focus &&  <DatesContainer 
                   className={transitioning === true ? "fading" : null} 
                   onAnimationEnd={transitioning === true ? () => this.handleFade() : null}
                 /> 
      }
    )
  }
}`

The difference between my answer and previous is you're able to set specific actions to certain animation keyframes.我的答案与之前的答案之间的区别在于您可以为某些动画关键帧设置特定的动作。

The key point is to provide animation name as a function parameter关键是提供动画名称作为函数参数

CSS CSS

.Modal {
    position: fixed;
    top: 30%;
    left: 25%;
    transition: all 0.3s ease-out;
}
.ModalOpen {
    animation: openModal 0.4s ease-out forwards;
}
.ModalClosed {
    animation: closeModal 0.4s ease-out forwards;
}

@keyframes openModal {
    0% { transform: translateY(-100%); }
    100% { transform: translateY(0);   }
}

@keyframes closeModal {
    0% { transform: translateY(0); }
    100% { transform: translateY(-100%);}
}

JS JS

const modal = ({ 
  isShown, isMounted, 
  initiateUnmountAction, unmountAction
}) => {
  const cssClasses = [
    "Modal",
    props.isShown ? "ModalOpen" : "ModalClosed"
  ];
  return (
    <Fragment>
      {isMounted && <div className={cssClasses.join(' ')}
        onAnimationEnd={event => 
          {event.animationName == "closeModal" && unmountAction}
      }>
        <h1>A Modal</h1>
        <button className="Button" onClick={initiateUnmountAction}>
          Dismiss
      </button>
      </div>}
    </Fragment>

  );
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM