React只给单击的元素赋予动画

时间:2019-04-23 10:06:01

标签: javascript css reactjs

我希望在单击按钮后添加微调器动画,当获得响应时,微调器应该消失了。到目前为止,效果很好,但问题是我渲染包含许多元素的列表,每个元素都有自己的删除按钮,单击一个按钮时,动画将添加到列表的所有元素中。我希望它只出现在列表中此特定单击元素旁边的一次。

 const displayCertificateList = (
  classes,
  mainStatus,
  handleDeleteSingleCertificate,
  animateDelete 
) => {
    return mainStatus.map((el, i) => {
      return (
        <div className={classes.certificatesListContainer} style={{border:'none'}}>
          <List key={i} style={{padding: '10px'}}>
            <ListItem style={{ padding: "0 0 0 20px" }}>
              <ListItemText
                className={classes.certificatesList}
                primary={
                  <Typography type="body2" style={{ fontWeight: "bold" }} className={classes.certificatesListFont}>
                    Valid until:
                  </Typography>
                }
                secondary={
                  <Typography
                    type="body2"
                    className={classNames(
                      classes.certificatesListSecondArgument,
                      classes.certificatesListFont,
                      el.expiresIn > 90 ? classes.green : classes.red
                    )}
                  >
                    {el.validUntil.slice(0,9)} ({el.expiresIn} days)
                  </Typography>
                }
              />
            </ListItem>
          </List>
          <div className={classes.certificatesBtn}>
            <Button
              variant="contained"
              size="small"
              color="secondary"
              className={classes.button}
              onClick={() => {
                if (
                  window.confirm(
                    `Are you really sure?
                  )
                )
                  handleDeleteSingleCertificate(el, i);
              }}
            >
              <DeleteIcon className={classes.leftIcon} />
              Delete
            </Button>
            <div style={{left: '-50%',top: '30%'}} className={classNames(animateDelete ? classes.spinner : null)}></div>
          </div>
        </div>
      );
    });
  } else {
    return (
      <div>
        <Typography component="h1" variant="h6">
          The applet is not innitialized, please initialize it first
        </Typography>
      </div>
    );
};

在父组件中:

 handleDeleteSingleCertificate = (el, i) => {
    this.setState({animatingDelete: true})

    this.make_call(
      this.state.selected, 
      (res) => {
        console.log(res)
        this.setState({animatingDelete: false})
      }
    )
  }

并像这样传递它:

        {this.state.view === 'certificates' && this.state.certificates && displayCertificates(classes, fakeData, this.handleDeleteSingleCertificate,  this.state.animatingDelete)}

2 个答案:

答案 0 :(得分:1)

我建议将displayCertificateList函数组件变成有状态组件,并将animatingDelete存储在其中-因为这是契约中该特定项目的状态。

class ListItem extends React.Component {
  state = {
    isDeleting: false
  }

  handleDelete = () => {
    const { onDelete, id } = this.props;
    onDelete(id);
    this.setState({
      isDeleting: true
    })
  }
  
  render(){
    const { isDeleting } = this.state;
    return (
      <li>
        <button onClick={this.handleDelete}>Delete {isDeleting && '(spinner)'}</button>
      </li>
    )
  }
}

class List extends React.Component {
  state = {
    listItems: [
      {id: 1},
      {id: 2}
    ]
  }
  
  handleDelete = id => {
      console.log('delete ' + id);
      // do the async operation here and remove the item from state
  }
  
  render(){
    const { listItems } = this.state;
    return (
      <ul>
        {listItems.map(({id}) => (
          <ListItem id={id} key={id} onDelete={this.handleDelete} />
        ))}
      </ul>
    )
  }
}

ReactDOM.render(<List />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root" />

答案 1 :(得分:0)

我认为,最好使用count而不是animatingDelete进行标记。您可以在单击删除按钮时加1,然后在完成时减去1。当count等于0时,隐藏旋转,否则显示它。