如何推迟this.props.onClick()直到CSS动画完成?

时间:2017-08-18 00:54:39

标签: reactjs onclick nextjs

我正在从我的页面调用自定义NanoButton组件以及onClick指令以路由到另一个页面:

// Page.js
import { Component } from 'react';
import Router from 'next/router';
class Page2 extends Component {
  render() {
    return(
      <NanoButton type="button" color="success" size="lg" onClick={() => Router.push('/about')}>About</NanoButton>
    )
  }
}

单击按钮(NanoButton组件)时,我想先执行一些内部代码,然后再继续作为道具进入onClick。通过这个内部代码,我试图模拟持续600毫秒的材料设计涟漪效应。我就是这样做的:

import { Component } from 'react';
import { Button } from 'reactstrap';

class NanoButton extends Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this);
  }
  onClick(e) {
    this.makeRipple(e);
    this.props.onClick();
  }
  makeRipple(e) {
    const elements = e.target.getElementsByTagName('div');
    while (elements[0]) elements[0].parentNode.removeChild(elements[0]);
    const circle = document.createElement('div');
    e.target.appendChild(circle);
    const d = Math.max(e.target.clientWidth, e.target.clientHeight);
    circle.style.width = `${d}px`;
    circle.style.height = `${d}px`;
    const rect = e.target.getBoundingClientRect();
    circle.style.left = `${e.clientX - rect.left - (d / 2)}px`;
    circle.style.top = `${e.clientY - rect.top - (d / 2)}px`;
    circle.classList.add('ripple');
  }
  render() {
    return (
      <Button
        className={this.props.className}
        type={this.props.type}
        color={this.props.color}
        size={this.props.size}
        onClick={this.onClick}
      >
        {this.props.children}
      </Button>
    );
  }
}

export default NanoButton;

正如您所看到的,我需要在makeRipple之前执行this.props.onClick方法。最初,它似乎没有这样做。然而,在进一步测试之后,事实证明方法确实以正确的顺序运行,除了路由(在this.props.onClick中编码)立即发生并且样式为600毫秒的波纹动画未获得有机会跑。使这个动画发生的CSS是:

button {
    overflow: hidden;
    position: relative;
}

button .ripple {
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.7);
    position: absolute;
    transform: scale(0);
    animation: ripple 0.6s linear;
}

@keyframes ripple {
    to {
        transform: scale(2.5);
        opacity: 0;
    }
}

如何让this.props.onClick仅运行 AFTER 动画完成?我试着像这样设置超时:

setTimeout(this.props.onClick(), 600);

但这会引发错误。

注意:我正在使用NextJS进行服务器端渲染,如果这有任何区别的话。

1 个答案:

答案 0 :(得分:2)

有很多方法可以做到,例如 function __Construct(){ $this->load->database(); } function select_data($field , $table , $where = '' , $join_array = '' , $limit = '' , $order = ''){ $this->db->select($field); $this->db->from($table); if($where != ""){ $this->db->where($where); } if($join_array != ''){ if(in_array('multiple',$join_array)){ foreach($join_array['1'] as $joinArray){ $this->db->join($joinArray[0], $joinArray[1]); } }else{ $this->db->join($join_array[0], $join_array[1]); } } if($limit != ""){ if(count($limit)>1){ $this->db->limit($limit['0'] , $limit['1']); }else{ $this->db->limit($limit); } } if($order != ""){ $this->db->order_by($order['0'] , $order['1']); } return $this->db->get->result_array(); die(); } Promise等。 但是,如果您尝试async/await,请使用

setTimeout

setTimeout(() => this.props.onClick(), 600);

你的案子:

setTimeout(this.props.onClick, 600);

将无效,因为此行会将setTimeout(this.props.onClick(), 600); 的结果传递给第一个参数,而不是传递整个函数。