Я создаю «поддельный» компонент просмотра стека, у меня есть массив идентификаторов, где каждый идентификатор загружает сложные объекты в карту, поэтому мне нужно предварительно загрузить 2 карты и затем при каждом добавлении клика добавлять новая карта, чтобы я мог получить более плавный опыт вставки.
Я не использую useTransition
, потому что каждая карта монтируется лениво, а впечатление не гладкое (из-за времени монтирования).
Я получил то, что хотел, однако я создаю потраченные впустую пружины (см. Журнал консоли), это был единственный способ создать новую пружину для каждой добавленной карты, предыдущая весна «запоминает» текущую позицию и я не могу их повторно использовать
есть ли лучший способ добиться этого?
codesandbox: https://codesandbox.io/s/jolly-stonebraker-fjd19?file= / src / App.jsx
import React, { useState, useEffect } from "react";
import { useSpring, animated, useSprings } from "react-spring";
import "./styles.css";
import Card from "./Card";
let data = [];
for (let i = 0; i < 50; i++) {
data.push(i);
}
export default function App() {
const [currentData, setCurrentData] = useState([data[0], data[1]]);
const [currentIndex, setCurrentIndex] = useState(0);
const [springs, set] = useSprings(currentData.length, idx => {
const isLast = idx === currentData.length - 1;
console.log("init uses spring");
return {
from: { x: isLast ? 300 : 0 },
onRest: () => {
console.log("on reset");
setCurrentIndex(currentIndex + 1);
const newArr = [...currentData];
newArr.push(data[currentIndex + 2]);
newArr[currentIndex] = null;
setCurrentData(newArr);
}
};
});
// const springs = [goAwayProps, slideInProps];
useEffect(() => {
console.log("mount");
}, []);
const handleNext = () => {
// setCurrentData([data[currentIndex + 1], data[currentIndex + 2]]);
set(idx => {
const isLast = idx === currentData.length - 1;
return {
to: async next => {
await next({
x: isLast ? 0 : -80
});
}
};
});
};
console.log(currentData);
return (
<div className="App">
<button onClick={handleNext}>next</button>
<div className="container">
{currentData.map((d, i) => {
if (d === null) return null;
const { x } = springs[i];
return (
<animated.div
style={{
transform: x.interpolate(x => `translate3d(${x}px,0,0)`)
}}
>
<Card>{d}</Card>
</animated.div>
);
})}
</div>
</div>
);
}