搜索过滤器 NextJS 14 无法在服务器组件(page.tsx)上使用 useState

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

我目前正在学习 NextJS 和 React,并且我一直在努力弄清楚如何制作输入搜索过滤器来过滤表格。

我看过很多关于使用 useSearchParams 的视频和评论,但这不是我想做的事情。

我想实时过滤,每次用户在输入上按下一个键时都会刷新表,并且随着我在输入过滤器中写入更多内容,行数会减少。

我该怎么办?

这是我的搜索输入文件:

"use client"

import { Input } from "@/components/ui/input"

import { useState} from 'react';

export default function InputSearch() {
    const [search, setSearch] = useState('')
    return(
        <Input 
            placeholder="Buscar categoría..."
            onChange={(e) => setSearch(e.target.value)}
            value={search}
        />
    )
}

这是我的 page.tsx 文件(服务器组件)

import Navbar from "@/components/navbar";
import {Heading} from "@/components/ui/heading"
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion" 
import {Button} from "@/components/ui/button"
import {db} from "@/lib/db"
import InputSearch from "@/app/table/categorias/components/search-input";

const SearchCategoryPage = async() => {

  const categorias = await db.table_Categories.findMany({
    orderBy: {
      name: "asc",
    }
  })
  const subcategorias = await db.table_Subcategories.findMany({
    orderBy: {
      name: "asc",
    }
  })

  return(
    <div>
    <Navbar></Navbar>
      <Heading 
      title="Categorías" 
      description="Description"
      />
      <div className="pl-4 pr-4 w-[100%]">
      <InputSearch/>
      <Accordion type="single" collapsible className="w-full">
      {categorias
      .map((filteredCategoria) => (
        <AccordionItem key={filteredCategoria.id} value={filteredCategoria.name}>
          <AccordionTrigger>{filteredCategoria.name}</AccordionTrigger>
          <AccordionContent>
            {subcategorias
            .filter((subcategoria) => subcategoria.id_category === filteredCategoria.id)
            .map((filteredSubcategoria) => (
                <div>
                  <Button variant="link" key={filteredSubcategoria.id}>{filteredSubcategoria.name}</Button>  
                </div>            
                ))}
          </AccordionContent>
        </AccordionItem>
      ))}
    </Accordion>
    </div>
    </div>
  )
}

export default SearchCategoryPage

提前致谢!

嗨。

我目前正在学习 NextJS 和 React,并且我一直在尝试弄清楚如何制作输入搜索过滤器来过滤表格。

我看过很多关于使用 useSearchParams 的视频和评论,但这不是我想做的事情。

我想实时过滤,每次用户在输入上按下一个键时都会刷新表,并且随着我在输入过滤器中写入更多内容,行数会减少。

我该怎么办?

这是我的搜索输入文件:

"use client"

import { Input } from "@/components/ui/input"

import { useState} from 'react';

export default function InputSearch() {
    const [search, setSearch] = useState('')
    return(
        <Input 
            placeholder="Buscar categoría..."
            onChange={(e) => setSearch(e.target.value)}
            value={search}
        />
    )
}

这是我的 page.tsx 文件(服务器组件)

import Navbar from "@/components/navbar";
import {Heading} from "@/components/ui/heading"
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion" 
import {Button} from "@/components/ui/button"
import {db} from "@/lib/db"
import InputSearch from "@/app/table/categorias/components/search-input";

const SearchCategoryPage = async() => {

  const categorias = await db.table_Categories.findMany({
    orderBy: {
      name: "asc",
    }
  })
  const subcategorias = await db.table_Subcategories.findMany({
    orderBy: {
      name: "asc",
    }
  })

  return(
    <div>
    <Navbar></Navbar>
      <Heading 
      title="Categorías" 
      description="Description"
      />
      <div className="pl-4 pr-4 w-[100%]">
      <InputSearch/>
      <Accordion type="single" collapsible className="w-full">
      {categorias
      .map((filteredCategoria) => (
        <AccordionItem key={filteredCategoria.id} value={filteredCategoria.name}>
          <AccordionTrigger>{filteredCategoria.name}</AccordionTrigger>
          <AccordionContent>
            {subcategorias
            .filter((subcategoria) => subcategoria.id_category === filteredCategoria.id)
            .map((filteredSubcategoria) => (
                <div>
                  <Button variant="link" key={filteredSubcategoria.id}>{filteredSubcategoria.name}</Button>  
                </div>            
                ))}
          </AccordionContent>
        </AccordionItem>
      ))}
    </Accordion>
    </div>
    </div>
  )
}

export default SearchCategoryPage

reactjs next.js search frontend
1个回答
0
投票

有多种方法可以实现这种方法。其中之一是使用状态管理,如

useContext
redux
来获取用户输入的搜索值并传递到所需的组件。不过,我建议使用 URL 搜索参数,这意味着将用户的输入查询转换为 URL 搜索查询。这样当前页面就可以直接访问这个变量了。 Next.js官方文档也推荐了这种方法。您可以参考https://nextjs.org/learn/dashboard-app/adding-search-and-pagination

    // InputSearch
    "use client"
    
    import { Input } from "@/components/ui/input"
    import { useSearchParams } from 'next/navigation'
    
    export default function InputSearch() {
        const params = new URLSearchParams(searchParams)
        
        return(
            <Input 
                placeholder="Buscar categoría..."
                onChange={(e) => {
                  if (e.target.value) {
                    params.set('query', e.target.value);
                  } else {
                    params.delete('query');
                  }
                }}
                value={params.query}
            />
        )
    }
        
    // SearchCategoryPage
                 .
                 . 
                 .
    import InputSearch from "@/app/table/categorias/components/search-input";

    const SearchCategoryPage = async({searchParams}) => {
      const query = searchParams?.query || '';
      const categorias = await db.table_Categories.findMany({
        orderBy: {
          name: "asc",
        },
        // do your search query...
      })
      const subcategorias = await db.table_Subcategories.findMany({
        orderBy: {
          name: "asc",
        },
        // do your search query...
      })
    
      return(
        <div>
        <Navbar></Navbar>
          <Heading 
          title="Categorías" 
          description="Description"
          />
          <div className="pl-4 pr-4 w-[100%]">
          <InputSearch/>
          <Accordion type="single" collapsible className="w-full">
          {categorias
          .map((filteredCategoria) => (
            <AccordionItem key={filteredCategoria.id} value={filteredCategoria.name}>
              <AccordionTrigger>{filteredCategoria.name}</AccordionTrigger>
              <AccordionContent>
                {subcategorias
                .filter((subcategoria) => subcategoria.id_category === filteredCategoria.id)
                .map((filteredSubcategoria) => (
                    <div>
                      <Button variant="link" key={filteredSubcategoria.id}>{filteredSubcategoria.name}</Button>  
                    </div>            
                    ))}
              </AccordionContent>
            </AccordionItem>
          ))}
        </Accordion>
        </div>
        </div>
      )
    }
    
    export default SearchCategoryPage
© www.soinside.com 2019 - 2024. All rights reserved.