【发布时间】:2019-06-20 04:44:41
【问题描述】:
在 React 中创建交换列表时,我遇到了一个奇怪的转换错误。列表的工作方式很简单:单击一个元素 (A),它的背景过渡到较浅的颜色,然后单击另一个 (B),它们交换位置,元素 A,现在在一个新位置,过渡回原色。
至少当元素 A 的索引比元素 B 高时会发生这种情况。反之,交换后的过渡被切断。
我设法使用window.requestAnimationFrame 找到了解决方法,但这并不完美。过渡的状态不会被保留,这意味着它总是从完整的浅色过渡回来。在这里没那么重要,但这在我的另一个项目中是一个问题。有时过渡也会被剪掉。
代码很简单。需要注意的是元素在交换后保留了它们的键。我创建了a code sandbox 供你玩耍。
import React, { useState } from "react";
const Item = props => {
let classes = "item";
if (props.selected) {
classes += " selected";
}
return (
<div className={classes} onClick={props.onClick}>
{props.value}
</div>
);
};
const App = () => {
const [list, setList] = useState([1, 2, 3]);
const [selected, setSelected] = useState(-1);
const select = index => {
setSelected(index);
};
const swap = index => {
const newList = [...list];
[newList[index], newList[selected]] = [newList[selected], newList[index]];
setList(newList);
setSelected(-1);
};
// The workaround that kind of works, but is not perfect.
// const swap = index => {
// const newList = [...list];
// [newList[index], newList[selected]] = [newList[selected], newList[index]];
// setList(newList);
// window.requestAnimationFrame(() => {
// setSelected(index);
// window.requestAnimationFrame(() => {
// setSelected(-1);
// });
// });
// };
const onClick = selected < 0 ? select : swap;
const items = list.map((value, index) => (
<Item
key={value}
value={value}
selected={selected === index}
onClick={onClick.bind(this, index)}
/>
));
return <div className="list">{items}</div>;
}
以下是关键的 CSS 规则:
.item {
background: #0b7189; // darker
transition: background-color 1s;
}
.item.selected {
background-color: #228cdb; //lighter
}
我正在寻找比我的解决方法更可靠的解决方案。
所有帮助将不胜感激! :)
【问题讨论】:
标签: javascript css reactjs css-transitions