我正在开发一个简单的Reaction应用程序,它涉及到在棋盘上移动瓷砖.该应用程序使用css来制作动画,并使用Reaction状态来跟踪瓷砖的位置.我有一个转换函数,可以更新瓷砖的位置,希望每个瓷砖都能动画显示到它的新位置.然而,我注意到,在调用转换函数后,带有key=2
和key=3
的瓷砖的动画不会触发,尽管状态更新正确,其他瓷砖的动画也如预期的那样.
App.tsx
import './Index.css';
import { useState, Fragment } from 'react';
function bcls(...parts) {
return parts.filter(Boolean).join(' ');
}
const initState = [
{ x: 0, y: 0, key: 1, moved: false },
{ x: 2, y: 0, key: 2, moved: false },
{ x: 1, y: 1, key: 3, moved: false },
{ x: 2, y: 1, key: 4, moved: false },
{ x: 3, y: 2, key: 5, moved: false },
];
const transitionState = [
{ x: 0, y: 3, key: 1, moved: true },
{ x: 2, y: 3, key: 4, moved: true },
{ x: 3, y: 3, key: 5, moved: true },
{ x: 2, y: 2, key: 2, moved: true },
{ x: 1, y: 3, key: 3, moved: true },
];
export default function App() {
const [tiles, setTiles] = useState(initState);
function transition() {
setTiles(transitionState);
}
function reset() {
setTiles(initState);
}
return (
<Fragment>
<button onClick={transition}>transition</button>
<button onClick={reset}>reset</button>
<div className="board">
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
<div className="cell"></div>
{tiles.map((tile) => (
<div
key={tile.key}
className={bcls('tile', tile.moved && 'tile-moved')}
style={{ '--x': tile.x, '--y': tile.y }}
>
{tile.key}
</div>
))}
</div>
</Fragment>
);
}
Index.css
.board {
--grid: 4;
--size: 50px;
--gap: 12px;
background-color: #8f8b8b;
padding: var(--gap);
position: relative;
display: grid;
gap: var(--gap);
grid-template-columns: repeat(var(--grid), var(--size));
grid-template-rows: repeat(var(--grid), var(--size));
}
.cell {
background-color: #aaa;
}
.tile {
background-color: #afe544;
width: var(--size);
height: var(--size);
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: calc(var(--y) * (var(--size) + var(--gap)) + var(--gap));
left: calc(var(--x) * (var(--size) + var(--gap)) + var(--gap));
}
.tile-moved {
transition: 4000ms ease-in-out;
}
Main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
这是一张StackBlitz Demo美元.
我希望在调用转换函数时,每个平铺都能平滑地转换到其新位置.这适用于除具有key=2
和key=3
的平铺之外的所有平铺.对于这两个平铺,它们在没有任何动画的情况下跳到其新位置.