我正在使用
useTransition
中的 react spring
为博客构建动画文字的砖石网格显示。我的工作很大程度上基于 React Spring 的砖石网格的官方 Codesandbox 演示,可以在这里找到:https://codesandbox.io/embed/26mjowzpr
我的作品可以在这里找到:https://codesandbox.io/s/qrzn-issue-2-david-byrne-8s7bo?file=/src/App.js:1267-1293
您会在我的代码和框中注意到,如果您单击底部的一个小头,则会发生转换,但随后页面将重新渲染大约 20 次,我不明白为什么。
我认为这与我调用
useTransition
有关,但我完全不知所措
const leftTransitions = useTransition(leftGridItems, item => item.word, {
from: ({ xy, width, height }) => {
return {
xy: [xOffset, yOffset],
width,
height,
opacity: 0
};
},
enter: ({ xy, width, height }) => ({ xy, width, height, opacity: 1 }),
update: ({ xy, width, height }) => ({ xy, width, height }),
leave: ({ xy, width, height }) => {
return {
xy: [xOffset, yOffset],
opacity: 0
};
},
config: { mass: 5, tension: 500, friction: 100 },
trail: 25
});
如果有人感兴趣,如果您更新到 v9,这将不再是问题。详细信息请参见此处的变更日志:https://www.react-spring.io/log
我通过添加溢出来修复(在这种情况下,我使用的是顺风,所以我只是使用
overflow-x-scroll
和 max-w-full
。这是示例
<div
className={cn(
"w-full max-w-full disable-scrollbars overflow-x-scroll h-full flex flex-row justify-between phonewide:justify-between items-center",
"tansition-all duration-300 ease-in-out"
)}
>
<ChevronLeft
className="phonewide:flex sm:flex lg:w-16 lg:h-16 md:w-10 md:h-10 sm:h-7 sm:w-7 w-7 h-7 text-gray-500"
onClick={() => {
setDirection("left");
if (idx === 0) {
setIdx(DUM_BATTERY.length - 1);
return;
}
setIdx((state) => (state - 1) % 4);
}}
/>
{transitions((style, item, ts) => (
<animated.div
key={item.id}
className={cn(
"phonewide:space-x-5 sm:space-x-5 space-x-2 lg:space-x-10",
"flex flex-col items-center justify-center",
"phonewide:flex-row md:flex-row sm:flex-row",
"transition-all duration-700 ease-in-out"
)}
style={{
...style,
width: "100%",
}}
>
<div>
<Image
src={getBatteryImage(item?.battery?.picture)}
width={200}
height={220}
alt="Battery image"
className="rounded-lg h-28 w-28 sm:h-60 sm:w-60 lg:h-72"
/>
</div>
<div className="flex flex-col justify-between">
<div>
<p className="text-lg lg:text-xl font-semibold mt-4 sm:mt-0">
{item.name}
</p>
<p className="text-base text-gray-500">
Capacity: {batteryMeta.capacity} kWh
</p>
<p className="text-base text-gray-500">
Warranty: {batteryMeta.warranty} Years
</p>
</div>
{/* desktop view */}
<div className="flex-col space-y-2 mt-2 w-full hidden sm:flex">
<div className="flex items-center justify-between phonewide:justify-center space-x-4 bg-gray-100 rounded-lg px-4 py-2 phonewide:w-min w-full">
<button className="text-xl font-semibold text-gray-600">
-
</button>
<span className="text-xl font-medium text-gray-800">1</span>
<button className="text-xl font-semibold text-gray-600">
+
</button>
</div>
<Button>Select Battery</Button>
</div>
</div>
</animated.div>
))}
<ChevronRight
className="phonewide:flex sm:flex lg:w-16 lg:h-16 md:w-10 md:h-10 sm:h-7 sm:w-7 w-7 h-7 text-gray-500"
onClick={() => {
setDirection("right");
if (idx === DUM_BATTERY.length - 1) {
setIdx(0);
return;
}
setIdx((state) => (state + 1) % 4);
}}
/>
</div>
配置:
const [direction, setDirection] = React.useState("right");
const [idx, setIdx] = React.useState(0);
const transitions = useTransition(DUM_BATTERY[idx], {
from: {
opacity: 0,
transform:
direction === "left" ? "translateX(-100%)" : "translateX(100%)",
},
enter: { opacity: 1, transform: "translateX(0%)" },
leave: {
opacity: 0,
transform:
direction === "left" ? "translateX(100%)" : "translateX(-100%)",
},
config: {
...config.wobbly,
duration: 700,
},
reset: true,
exitBeforeEnter: true,
});