我用Next.js 14/App Router制作了一个照片转盘。它几乎完成了,但我不明白为什么当我移动到另一张照片时,当前照片(应该显示的一张照片)会消失。
Codepen
显示了我正在尝试修复的坏功能。使用箭头键选择下一张和上一张照片。
我的直觉告诉我,这与我在useReducer()挂钩中更新当前和以前的照片的方式有关,但我不知道如何修复它。我在SO上寻找解决方案,使用Copilot和一般谷歌搜索,但仍然停滞不前。
有什么前进的想法吗?谢谢
*我知道reducer函数传统上是在组件之外定义的,但我的函数需要访问照片道具,我不想每次发送动作时都传递所有照片。
*Image类名上的“隐藏”类是Tailwind版本的“display:none”。这与将“隐藏”道具添加到Image元素不同。
function GalleryCarousel({ photos }) {
const [navStates, dispatch] = useReducer(galleryNavReducer, {
current: 0,
prev: photos.length - 1,
currentAnimation: "",
prevAnimation: "",
});
const mainRef = useRef(null);
// Focus to <main> when component mounts
useEffect(() => {
mainRef.current?.focus();
}, []);
function galleryNavReducer(state, action) {
switch (action.type) {
case "PREV":
return {
current: state.current === 0 ? photos.length - 1 : state.current - 1,
prev: state.current,
currentAnimation: "rotate-out-left",
prevAnimation: "rotate-in-right",
};
case "NEXT":
return {
current: state.current === photos.length - 1 ? 0 : state.current + 1,
prev: state.current,
currentAnimation: "rotate-out-right",
prevAnimation: "rotate-in-left",
};
default:
return state;
}
}
function handleKeyDown(e: KeyboardEvent) {
switch (e.key) {
case "ArrowLeft":
dispatch({ type: "PREV" });
break;
case "ArrowRight":
dispatch({ type: "NEXT" });
break;
default:
console.log("Some other key was pressed.");
}
}
return (
<main
tabIndex={0} onKeyDown={handleKeyDown} ref={mainRef}
className="p-4 outline-none w-full h-full flex items-center justify-center"
>
<div className="relative w-full h-full flex items-center justify-center">
{photos.map((p, i) => {
return (
<Image
key={p.id}
src={p.url}
width={p.width}
height={p.height}
alt={p.description}
className={`object-contain layout-responsive w-[200px] max-h-full max-w-full ${
i === navStates.current
? `${navStates.currentAnimation} block`
: i === navStates.prev
? `${navStates.prevAnimation} hidden`
: "hidden"
}`}
priority={i === 0}
/>
);
})}
</div>
</main>
);
}