实现思路
- 在
getSnapshotBeforeUpdate
方法中,记录删除项的索引位置和高度等相关信息。
- 在组件更新后,根据记录的信息,为剩余列表项添加相应的CSS过渡动画,使它们平滑地填补空缺位置。
- 使用CSS的
transition
属性定义过渡效果。
核心代码片段
import React, { Component } from 'react';
import './styles.css'; // 引入CSS文件定义过渡效果
class DynamicList extends Component {
constructor(props) {
super(props);
this.state = {
items: ['Item 1', 'Item 2', 'Item 3']
};
this.handleDelete = this.handleDelete.bind(this);
}
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevState.items.length > this.state.items.length) {
// 找到删除项的索引
const deletedIndex = prevState.items.findIndex(item =>
this.state.items.indexOf(item) === -1
);
// 获取删除项的高度(假设列表项有固定高度)
const deletedItemHeight = document
.querySelector(`.list-item:nth-child(${deletedIndex + 1})`)
.offsetHeight;
return { deletedIndex, deletedItemHeight };
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot) {
const { deletedIndex, deletedItemHeight } = snapshot;
// 为剩余列表项添加过渡效果
const listItems = document.querySelectorAll('.list-item');
for (let i = deletedIndex; i < listItems.length; i++) {
listItems[i].style.transform = `translateY(-${deletedItemHeight}px)`;
listItems[i].style.transition = 'transform 0.3s ease';
}
setTimeout(() => {
// 移除过渡效果
for (let i = deletedIndex; i < listItems.length; i++) {
listItems[i].style.transform = 'translateY(0)';
listItems[i].style.transition = 'none';
}
}, 300);
}
}
handleDelete(index) {
const { items } = this.state;
items.splice(index, 1);
this.setState({ items });
}
render() {
const { items } = this.state;
return (
<div className="list">
{items.map((item, index) => (
<div key={index} className="list-item">
{item}
<button onClick={() => this.handleDelete(index)}>Delete</button>
</div>
))}
</div>
);
}
}
export default DynamicList;
styles.css
.list-item {
padding: 10px;
border-bottom: 1px solid #ccc;
}