0

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

目前我正在尝试使用 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)在具有业务逻辑的主要组件中,我设置了参考:

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;
}

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

最好的问候,康斯坦丁

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

更新:

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 钩子等。但仍然无法获得所需的结果,它在不应用淡入淡出动画的情况下将其移除。

4

2 回答 2

1

您创建wrapperRef并在每次迭代时覆盖它,map以便它保存最后一个表行的引用。这就是为什么你会看到最后一行淡出。

您可能需要一个参考数组,以便您拥有每一行的参考。根据表的大小,您可能应该寻找其他解决方案,因为不建议过度使用 refs

这种方法可能是最好的。

于 2020-06-10T23:14:31.713 回答
1

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

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

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

于 2021-01-11T21:20:24.980 回答