【问题标题】:Animation in React: how can I make a table row from a dynamic table fade out on delete?React 中的动画:如何使动态表中的表行在删除时淡出?
【发布时间】:2020-06-10 22:59:08
【问题描述】:

我有一个反应应用程序,我试图让每个表格行在单击该表格行的相应按钮时淡出。这个想法是,当单击该行上的删除按钮时,整行将淡出,其下方的其余行将向上移动(不创建任何空白空间),如果它是被删除的最后一行,它将只是淡出,表格会变小。

目前我正在尝试使用 refs 和 CSS 来实现此功能,但是现在,例如,如果我单击第二行中的“删除”按钮 - 该行将立即被删除,没有任何动画,但在同时最后一行的内容将根据我设置的 CSS 样式淡出,并且那里会留下一个空的表格行。之后,任何其他元素都将被移除而没有任何淡出动画。

到目前为止,我已经完成了以下工作:

1) 一个创建动态表行的组件(任何必要的数据,包括 ref,都从具有业务逻辑的组件通过 useContext() 传递):

function TableData() {
  const { dataset, handleDeletion, wrapperRef } = React.useContext(Context)

  return dataset.map((item, index) => {
    const { id, name, year, color, pantone_value } = item
    return (
      <tr key={id} ref={wrapperRef}>
        <td>{year}</td>
        <td>{name}</td>
        <td style={{ backgroundColor: color, width: "100px" }} />
        <td>
          <button 
            value={id}
            type="button" 
            class="btn btn-outline-danger" 
            onClick={handleDeletion}>
            <i class="far fa-trash-alt"></i>
          </button>
        </td>
      </tr>
    )
  })
}

2) 在具有业务逻辑的主要组件中,我设置了 ref:

const wrapperRef = React.createRef()

3) 这是一个处理单击删除按钮的函数:

function handleDeletion(event) {
  const id = event.currentTarget.value

  const wrapper = wrapperRef.current
  wrapper.classList.add('fade')

  setDataset(prevDataset => prevDataset.filter(item => item.id !== parseInt(id)))
}

4) 简单的 CSS 动画:

.fade {
  opacity: 0;
  transition: opacity 5000ms;
}

您能否让我知道我在这里做错了什么以及需要修复什么才能使其按计划工作?

最好的问候, 康斯坦丁

附:我还将完整的代码附加到这篇文章中(以防万一),这里是这个项目的 pen 的链接。

更新:

1) 我在“tr”组件中添加了以下类名:

<tr key={id} className={toDelete && itemToDelete === id ? 'fade' : ''}>

2) 在主组件中,我添加了以下状态钩子:

const [ toDelete, setToDelete ] = React.useState(false)
const [ itemToDelete, setItemToDelete ] = React.useState('')

3) 并将删除函数更改为以下内容(添加了一个额外的 useEffect 应用于这些钩子被更改):

function handleDeletion(event) {
  const id = event.currentTarget.value

  setToDelete(true)
  setItemToDelete(id)

  //setDataset(prevDataset => prevDataset.filter(item => item.id !== parseInt(id)))
}

React.useEffect(() => {
  if (toDelete !== false && itemToDelete !== '') {
    setTimeout(() => {
      setDataset(prevDataset => prevDataset.filter(item => item.id !== parseInt(itemToDelete)))
    }, 500)
  }
}, [toDelete, itemToDelete])

我尝试了不同的方法,包括使用 setTimeout/setInterval,在 handleDeletion 函数中没有单独的 useEffect 钩子等。但仍然无法获得所需的结果,它是在不应用淡入淡出动画的情况下将其移除。

【问题讨论】:

    标签: javascript reactjs animation ref react-animations


    【解决方案1】:

    您创建wrapperRef 并用每个map 迭代覆盖它,以便它保存最后一个表行的引用。这就是您看到最后一行淡出的原因。

    您可能需要一个 ref 数组,以便拥有每一行的 ref。根据表的大小,您可能应该寻找其他解决方案,因为它不推荐给overuse refs

    This approach 可能是最好的。

    【讨论】:

    • 谢谢!向动态表的行添加动画的推荐方法是什么?
    • 现在答案中有一个代码笔链接。我会这样做。
    • 感谢笔中的建议。我试图在我的文件中实现它,但由于某种原因,它仍然在不应用动画的情况下将其删除。我在主帖末尾更新了问题描述。请你看一下。
    【解决方案2】:

    除了Darko的回答,你还可以在淡出后从DOM中删除该行。

    setTimeout(function() { that.setState({ isDeleted: true })}, 500);
    

    https://codepen.io/primaryobjects/pen/qBaMvrq

    【讨论】:

      猜你喜欢
      • 2012-01-06
      • 2020-10-04
      • 1970-01-01
      • 2020-03-20
      • 2020-07-28
      • 1970-01-01
      • 2015-11-12
      • 2020-12-30
      • 1970-01-01
      相关资源
      最近更新 更多