Next.js Discord

Discord Forum

How do I fetch data from server and then filter out certain pieces of it on the client side?

Unanswered
Ragdoll posted this in #help-forum
Open in Discord
RagdollOP
I'm currently fetching "projects" for my personal website from a Notion database using their API. I'm fetching these projects directly in a server component and then displaying them in a grid by passing them as props to <ProjectsGrid />.

How would I add a search bar that can filter out certain projects based on the input of the search bar? I don't want to refetch the projects, I just want to filter them out client side since there are so few of them.

The way I would do this in React and previous Next versions is lifting the state of the search bar to a higher component to then pass the search input to the projects grid. Problem is that this would require lifting the state up to the component that is also fetching the projects. It's like I need the higher component to essentially be both server and client.

What's the best solution? Do I make yet another higher component to fetch the projects and then make a client component below it that can hold the lifted state from search bar and also the project grid?

Here's the problem I have in code to help explain:

import { Project } from "@/types";
import { getAllProjects } from "@/lib/notion";
import ProjectsGrid from "@/components/projects/ProjectsGrid";

// Revalidate this route every hour (fetch new data)
export const revalidate = 3600;

export default async function Projects() {
    // Would hold state here normally
    // const [searchInput, setSearchInput] = useState<string>("");

    // Fetch projects directly from Notion database (need this to be server component for this)
    const projects: Project[] = await getAllProjects();

    return (
        <main className="text-slate-100 pt-8">
            <Searchbar searchInput={searchInput} setSearchInput={setSearchInput} />
            {/* Would filter the projects based on the searchInput in the ProjectsGrid component */}
            <ProjectsGrid projects={projects} searchInput={searchInput} />
        </main>
    );
}

1 Reply

Siberian Flycatcher
You can keep fetching data in server component, but move both search input and projects grid into a client component. Then pass data fetched from server component to client component and do filtering on the client.

//page.jsx
async function Page() {
  const projects = await fetch(...)
  return <FilterGrid projects={projects} />
}


//filter-grid.jsx
"use client"

function FilterGrid({projects}) {
  const [search, setSearch] = useState("")
  const filteredProjects = projects.filter((project) => {
    return project.title.toLowerCase().includes(search.toLowerCase());
  });
}

return (
  ...
  <input
    onChange={(e) => setSearch(e.target.value)}
    value={search} />
  ...
  {filteredPorjects.map(project => ...)}
)