#Passing Props Between Client and Server Components

17 messages · Page 1 of 1 (latest)

rustic flicker
#

Looking to get some guidance on the correct approach to pass props from a client component to a server component in NextJS 14 app router.

My use case:

I have a current Page.tsx in the root of /app that is a server component (default) and is fetching data from a Xata DB (SDK). I current have a search bar using searchParams within that same file to query the data in the URL "q?="

const xata = getXataClient();

export default async function Card({ searchParams }: { searchParams: { q: string } }) {
  let cards = null;
  if (searchParams.q) {
    const { records } = await xata.db.Network.search(searchParams.q, { 
      fuzziness: 1,
      boosters: [{ valueBooster: { column: 'PremiumMember', value: true, factor: 5 } }]
    }
    );
    cards = records;
  } else {
    cards = await xata.db.Network.filter({ProfileActive: true}).getMany({
      pagination: { size: 24 },
      fetchOptions: { next: { revalidate: "60" } },
    });
  }

This obviously works fine but does not feel "fast".

In order to search you have to hit enter to send the q request to the server and back. This causes a page refresh which also scrolls the users potentially elsewhere. Although still fairly quick it does not feel instant like other examples I've seen generally.

I'm wondering if refactoring this search bar out to a client component and passing down the q props to the page file would yield a "snappier" searching experience? This is stretching some of my React/NextJS knowledge but the leap I'm making is that since the Page.tsx data was fetched on the server, then it should be cached for the page session. Thus allowing the passed client search props to filter already cached data. Therefore snappy?

I may be missing a few links here. Would appreciate any guidance on if/how this pattern is supposed to work 🙏

autumn yachtBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

narrow surge
#

Yes next has a tutorial even on how to incorporate a search bar. The reason you're getting a refresh is, i assume, that your browser is doing a regular submit, so forcing a browser refresh, You need to have it that:

<form onSubmit={(e) => { 
 e.preventDefault();
router.push(`url&${someFunctionToEncodeYourSearchParams(e)}`);}}>
   <input />
</form>

As we have custom javascript, the search bar itself needs to be a client component.

rustic flicker
#

Ah ok! So I was on the right track. And placing it in the layout makes sense. I would need refactor my case a bit to create a sub layout file/route then as I only want the search on a certain page. I guess though the actual input form is still a client component that is imported into the layout I want it displayed in?

Either way this was exactly what I was looking for! Thanks so much for your insight!

#

As a followup, this approach would still not be what I call live type filtering. Because even though the search is a client component, its still using a form/onsubmit to pass the query to the server data set? Is it much different to get a dynamic search that would need debounce protection?

inland hare
#

or use window.location.search like this example if you don't need the searchParams on rendering

inland hare
rustic flicker
#

Ah ok thanks for the example link. I will give the router push a try. The Learn NextJS also talks about how to handle the debounce.

So on the server side where the data was fetch. When a user inputs a search term (either keystroke or whole term input) how does NextJS handle what segment of the data is queried? For example, in my app, my data is fetched from the DB but I have a limit so that only the first 24 rows are returned. What happens when a search term is entered? is the data from the first 24 thrown out to search the whole DB or some sort of hybrid action? I'm curious for the purpose of seeing how many extra requests might be made to the DB.

inland hare
rustic flicker
inland hare
rustic flicker
inland hare