Next.js“使用客户端”与服务器组件(glob)

问题描述 投票:0回答:1

嗨,我想在输入搜索栏时将图库不透明度设置为 50%。 但我觉得我不能将“使用客户端”与 glob 库一起使用。

以下是我的代码

应用程序/page.tsx

"use client";

import { useState } from "react";
import Gallery from "./ui/Gallery";
import SearchBar from "./ui/SearchBar";

export default function Home() {
  const [isSearching, setIsSearching] = useState(false);

  return (
    <div className="max-w-5xl m-auto mt-10">
      <SearchBar setIsSearching={setIsSearching} />
      <Gallery isSearching={isSearching} />
    </div>
  );
}

应用程序/ui/Gallery.tsx

import React from "react";
import { glob } from "glob";
import Image from "next/image";
import { randomUUID } from "crypto";

const Gallery = async ({ isSearching }) => {
  let images = await glob("public/images/*");
  images = images.map((image) => image.split("public")[1]);

  return (
    <div className={`flex ${isSearching ? "opacity-50" : ""}`}>
      {images.map((image) => (
        <Image
          key={randomUUID()}
          src={image}
          width={300}
          height={300}
          alt="gallery image"
        />
      ))}
    </div>
  );
};

export default Gallery;

应用程序/ui/SearchBar.tsx

import React from "react";

const SearchBar = ({ setIsSearching }) => {
  return (
    <div>
      <input
        type="text"
        className="w-full mb-4 border-2 border-gray-300 bg-white h-10 px-5 pr-16 rounded-lg text-sm focus:outline-none"
        onFocus={() => setIsSearching(true)}
      />
    </div>
  );
};

export default SearchBar;

以下错误

error

我看到了Next.js官方文档

  1. 数据获取 - https://nextjs.org/docs/app/building-your-application/data-fetching
  2. 渲染 - https://nextjs.org/docs/app/building-your-application/rendering
javascript reactjs next.js glob
1个回答
0
投票

虽然,我从youtube找到了答案(?可能是绕过), https://www.youtube.com/watch?v=zwQs4wXr9Bg&ab_channel=JackHerrington

我为可能有类似问题的人回答我的问题。

新代码使用 Route Handlers 获取图像。

应用程序/page.tsx

import Image from "next/image";
import Gallery from "./ui/Gallery";
import SearchBar from "./ui/SearchBar";
import GalleryWrapper from "./ui/GalleryWrapper";
import { useState } from "react";

export default function Home() {
  const [isSearching, setIsSearching] = useState(false);
  return (
    <div className="max-w-5xl m-auto mt-10">
      <SearchBar setIsSearching={setIsSearching} />
      <Gallery isSearching={isSearching} />
    </div>
  );
}

ui/Gallery.tsx

import React, { use } from "react";
import Image from "next/image";

const getImages = async () => {
  let images = await fetch("http://localhost:3000/api");
  return images.json();
};

const fetchedImages = getImages();

const Gallery = ({ isSearching }: { isSearching: boolean }) => {
  const images = use(fetchedImages);
  return (
    <div className={`flex gap-2 ${isSearching ? "opacity-50" : ""}`}>
      {images.map((image: string) => (
        <Image key={image} src={image} width={200} height={200} alt={image} />
      ))}
    </div>
  );
};


export default Gallery;

ui/SearchBar.tsx

import React, { Dispatch, SetStateAction } from "react";

const SearchBar = ({
  setIsSearching,
}: {
  setIsSearching: Dispatch<SetStateAction<boolean>>;
}) => {
  return (
    <div>
      <input
        type="text"
        className="border rounded-md w-full mb-2"
        onFocus={() => setIsSearching(true)}
        onBlur={() => setIsSearching(false)}
      />
    </div>
  );
};

export default SearchBar;

api/route.ts

import { glob } from "glob";

export async function GET(request: Request) {
  let images = await glob("public/images/*.png");
  images = images.map((image) => image.split("public")[1]);
  return new Response(JSON.stringify(images));
}

欢迎您为芽苗开发者提供更好的想法或建议。

© www.soinside.com 2019 - 2024. All rights reserved.