javascript - 使用 React 更改列表顺序的 CSS 动画
问题描述
在我的 React 应用程序中,我有一个“排名”页面。它有一个可以根据几个标准排序的列表。我想添加一个简单的 CSS 动画,以便在更改排序条件时,旧列表淡出和新排序列表淡入,而不是突然和立即更改。
我已经设法让列表在初始页面加载时进行动画处理。但是当排序标准改变时,列表会立即改变。我认为这可能是因为我不太了解 React 状态是如何工作的。非常感谢您的帮助 - 或指向可以澄清问题的手册的链接。
带走不必要代码的 JS:
function Ranking() {
const [items, setItems] = useState([]);
const [sortType, setSortType] = useState();
const [isSorted, setIsSorted] = useState();
// load items once on page load
useEffect(() => {
loadItems();
}, [])
// fetch items from api
function loadItems() {
fetch(
`/api/get`,
{
method: "GET",
mode: "cors"
})
.then((res) => res.json())
.then((data) => {
setItems((prevItems) => {
return [...prevItems, ...data] })
})
.catch((error) => {
console.log(error);
});
}
// sort items based on current sort type
function sortItems(type) {
console.log('starting sort...')
setIsSorted(false);
console.log('set isSorted to false: ', isSorted)
if (type === 1) {
return items.sort((a, b) => b.criteria1 - a.criteria1);
} else if (type === 2) {
return items.sort((a, b) => b.criteria2 - a.criteria2);
} else if (type === 3) {
return items.sort((a, b) => b.criteria3 - a.criteria3);
};
}
// sort items on render
useEffect(() => {
if (!sortType) {
setSortType(1);
}
if (items.length > 0) {
setItems(sortItems(sortType));
setIsSorted(true);
}
})
// when 'Criteria N' button is clicked, change sorting criteria accordingly
function handleSort(event) {
const name = event.target.name;
setIsSorted(() => {
setSortType(parseInt(name));
return false;
});
}
return <div className="ranking-container">
<button className="ranking-sort-btn" name="1" onClick={handleSort}>Criteria 1</button>
<button className="ranking-sort-btn" name="2" onClick={handleSort}>Criteria 2</button>
<button className="ranking-sort-btn" name="3" onClick={handleSort}>Criteria 3</button>
<div className={isSorted ? "ranking-item-loaded" : "ranking-item-not-loaded"}>
{items.map((item, index) => {
return <RankingItem item={item} key={index} isSorted={isSorted}/>
})
}
</div>
</div>
CSS:
.ranking-item-not-loaded {
opacity: 0;
transition: opacity 200ms ease-in;
}
.ranking-item-loaded {
opacity: 1;
transition: opacity 220ms ease-in;
}
解决方案
事实证明,状态变化突然中断了转换。从过渡切换到不依赖第二状态的正确动画解决了这个问题。
<div className={isSorted && "ranking-item-animated"} onTransitionEnd={handleTransitionEnd}>
.ranking-item-animated {
animation-duration: 1s;
animation-name: fadein;
}
@keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
推荐阅读
- java - 在 Web 服务器线程中出现 OutOfMemoryError 时,Spring 引导请求挂起
- flutter - 在颤振提供程序中关闭应用程序时保存数据
- django - 根据用户角色获取登录用户的django权限以显示/隐藏菜单
- node.js - 如何在 Firebase Hosting 和 Google App Engine 之间启用 CORS
- c - 输入数字的正确方法是什么?
- wpf - WPF上没有前缀的特定值的单选按钮绑定
- flutter - 如何从 Locale (flutter_localizations) 更改默认值?
- c# - 基于字符串值实例化类或对一组类进行分组而不使用接口
- python - 为什么 numpy.vectorize() 会改变标量函数的除法输出?
- f# - FSharpList 断言与 N Fluent?