👋 Saw your X post and wanted to share some suggestions for improving search.
Current State
Based on this commit, it looks like you currently:
Have various places that are passing functions of props into components related to search
Kick off a search by setting and then updating local react state
This calls tRPC to fetch new data based on the search value
A callback function eventually calls router.push to update the URL
There's an opportunity to simplify and consolidate this logic, while improving the UX. Right now, you're mostly using client components and tRPC. While there's nothing wrong with this, you could centralize searching into one component, which triggers a server component to fetch new data when the URL state changes.
Desired State
I believe the UX you want is:
Users can instantly type into an input and start searching
Searching starts immediately – you do not need to wait until enter is pressed / form is submitted
When a search is pending, show some visual feedback to the user
Allow for multiple searches / permutations to happen, without showing visual jank from entering/exiting search state
Indicate to the user searching is happening with some animation on the containing element / inline spinner
Don't block the UI or drop frames when trying into the input quickly
Proposed Solution
Here's one option. It's using a new feature of Next.js (on canary) but it's not required (you could use a normal <form>).
The <Search> component gets the initial search value from searchParams from a Server Component above
This value is stored into local state, as well as a deferred value
When there are changes in the input, the local state is updated and the form is submitted
Submitting the form updates the URL state with the ?search= query parameter (replaced, not pushed onto the stack)
This fires a React transition to the new URL, which means useFormStatus is pending
This now shows a loading spinner inline for the search input, but also adds an attribute to the DOM element
In other parts of our codebase, we can use CSS to look for that element and conditionally add an animation
This also includes a useEffect to focus the input on mount (optional)
This likely isn't perfect yet but it's closer in the direction you're looking for. Happy to help out. I'm trying to build a similar example of searching here: https://next-books-search.vercel.app
👋 Saw your X post and wanted to share some suggestions for improving search.
Current State
Based on this commit, it looks like you currently:
router.push
to update the URLThere's an opportunity to simplify and consolidate this logic, while improving the UX. Right now, you're mostly using client components and tRPC. While there's nothing wrong with this, you could centralize searching into one component, which triggers a server component to fetch new data when the URL state changes.
Desired State
I believe the UX you want is:
Proposed Solution
Here's one option. It's using a new feature of Next.js (on
canary
) but it's not required (you could use a normal<form>
).<Search>
component gets the initial search value fromsearchParams
from a Server Component above?search=
query parameter (replaced, not pushed onto the stack)useFormStatus
ispending
useEffect
to focus the input on mount (optional)This likely isn't perfect yet but it's closer in the direction you're looking for. Happy to help out. I'm trying to build a similar example of searching here: https://next-books-search.vercel.app