React - 如何等待和淡出?

IT技术 reactjs
2021-05-19 15:06:01

我有一个警告框来确认用户已成功订阅:

<div className="alert alert-success">
    <strong>Success!</strong> Thank you for subscribing!
</div>    

当用户发送电子邮件时,我将“订阅”状态更改为 true。

我想要的是:

  • 当订阅状态为真时显示警告框
  • 等待 2 秒
  • 让它淡出

我怎样才能做到这一点?

3个回答

2021 年 5 月更新:正如 tolga 和 Alexey Nikonov 在他们的回答中正确指出的那样,可以控制向transition-delay属性显示警报的时间(在原始问题中为 2 秒)和基于transitionendDOM 事件此外,现在建议使用钩子来处理组件的内部状态,而不是setState. 所以我更新了我的答案:

function App(props) {
  const [isShowingAlert, setShowingAlert] = React.useState(false);
  
  return (
      <div>
        <div
          className={`alert alert-success ${isShowingAlert ? 'alert-shown' : 'alert-hidden'}`}
          onTransitionEnd={() => setShowingAlert(false)}
        >
          <strong>Success!</strong> Thank you for subscribing!
        </div>
        <button onClick={() => setShowingAlert(true)}>
          Show alert
        </button>
        (and other children)
      </div>
    );
}

然后alert-hidden在 CSS类中指定延迟

.alert-hidden {
  opacity: 0;
  transition: all 250ms linear 2s; // <- the last value defines transition-delay
}

isShowingAlert事实上,的实际变化几乎是即时的:从假到真,然后立即从真到假。但是因为转换到 opacity: 0 延迟了 2 秒,所以用户会在这段时间内看到消息。

这个例子中随意使用Codepen


由于 React 将数据渲染到 DOM 中,因此您需要保留一个变量,该变量首先具有一个值,然后是另一个值,以便消息首先显示然后隐藏。您可以使用 jQuery 的 直接删除 DOM 元素fadeOut,但操作 DOM 会导致问题

所以,这个想法是,你有一个可以有两个值之一的特定属性。最接近的实现是一个布尔值。由于消息框始终位于 DOM 中,因此它是某个元素的子元素。在 React 中,元素是渲染组件的结果,因此当你渲染一个组件时,它可以有任意多的子元素。所以你可以给它添加一个消息框。

接下来,该组件必须具有特定的属性,您可以轻松更改该属性,并完全确定,一旦更改它,组件就会使用新数据重新呈现。这是组件状态!

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      showingAlert: false
    };
  }
  
  handleClickShowAlert() {
    this.setState({
      showingAlert: true
    });
    
    setTimeout(() => {
      this.setState({
        showingAlert: false
      });
    }, 2000);
  }
  
  render() {
    return (
      <div>
        <div className={`alert alert-success ${this.state.showingAlert ? 'alert-shown' : 'alert-hidden'}`}>
          <strong>Success!</strong> Thank you for subscribing!
        </div>
        <button onClick={this.handleClickShowAlert.bind(this)}>
          Show alert
        </button>
        (and other children)
      </div>
    );
  }
}

在这里,您可以看到,对于消息框,根据组件状态属性值(真实性)设置了alert-shownalert-hidden类名showingAlert然后,您可以使用transitionCSS 属性使隐藏/显示外观平滑。

因此,显然您需要在某个事件上更新组件状态,而不是等待用户单击按钮来显示消息框。

这应该是好的开始。接下来,尝试使用 CSS 过渡displayheight消息框的 CSS 属性,看看它的行为方式以及在这些情况下是否发生平滑过渡。

祝你好运!

附注。请参阅Codepen

正确的方法是使用 Transition 处理程序进行淡入/淡出

在 ReactJS 中,有一个合成事件等待淡出完成:onTransitionEnd

注意,不同的处理程序有不同的 css 效果。淡入淡出是一种过渡而不是动画效果。

这是我的例子:

const Backdrop = () => {
  const {isDropped, hideIt} = useContext(BackdropContext);
  const [isShown, setState] = useState(true);
  const removeItFromDOM = () => {
    debugger
    setState(false)
  };
  return isShown
    ? <div className={`modal-backdrop ${isDropped ? 'show' : ''} fade` } onClick={hideIt} onTransitionEnd={removeItFromDOM}/>
    : null
}

另一种方法是用 CSS3 过渡来解决这个问题。 https://www.tutorialspoint.com/css/css_animation_fade_out.htm

您可以向警报添加一个新类(如 .hidden),然后您可以将 .hidden 与您为警报定义的类相关联。

alert.hidden{
    // Here you can define a css transition
}

在这个解决方案中,您不必添加 setInterval 或任何东西,因为 css3 转换已经在浏览器渲染中处理它。