代码之家  ›  专栏  ›  技术社区  ›  marg

为什么当我选择下一张或上一张照片时,照片转盘中的当前照片会消失?[下一步/反应]

  •  0
  • marg  · 技术社区  · 1 年前

    我用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>
    );
    

    }

    0 回复  |  直到 1 年前