I have this search input component which it’s working well to filter the events results but I’m facing an issue when changing the router using the <Link />
Nextjs (v14 – App Router) component.
The homepage is http://localhost:3000/
and when I submit the search form it becomes http://localhost:3000/?search=test
. Note: whenever there is a search (a query string) it should keep the term as a defaultValue on the input.
The problem is that when I navigate to another page, for example, http://localhost:3000/past
the form is cleared out (which is correct since I’m not searching anything) but if I go back to the homepage again the input is still filled with the old search term even though there’s nothing in the URL anymore.
For better understaing, I will post few screens from these steps.
Step 1 – Homepage:
Step 2 – Making a search:
Step 3 – Navigating to another page:
Step 4 – Returning to the homepage
(on this stage, if I press F5 it works – the term is not presented on the input anymore)
This is my page.tsx:
import EventList from "@/components/EventList";
import Menu from "@/components/Menu";
import Pagination from "@/components/Pagination";
import { getEvents } from "@/server-functions/getEvents";
export type PageProps = {
params: {};
searchParams: { [key: string]: string };
};
export default async function Home(props: PageProps) {
const searchParams = props.searchParams;
const page = Number(searchParams.page);
const search = searchParams.search;
const eventsQuery = await getEvents({
period: "upcoming",
filter: searchParams.filter,
page: page || 1,
search: search,
});
return (
<main className="flex min-h-screen flex-col items-center px-12 py-6">
<Menu link="upcoming" filter={searchParams.filter} search={search} />
<EventList
eventsQuery={eventsQuery}
Pagination={
<Pagination
currentPage={page || 1}
totalCount={eventsQuery.totalCount}
pageSize={10}
query={searchParams}
/>
}
/>
</main>
);
}
And this is my SearchForm.tsx component, which receives the search
from the Menu.tsx component:
import { FiSearch } from "react-icons/fi";
interface SearchFormProps {
search: string;
}
const SearchForm: React.FC<SearchFormProps> = ({ search }) => {
console.log(`Search: ${search}`, new Date());
return (
<form
method="get"
className="flex items-center space-x-2 border-b border-gray-300 py-2 px-4 text-gray-700"
autoComplete="off"
>
<button type="submit" className="">
<FiSearch className="text-gray-400 w-5 h-5" /> {/* Search icon */}
</button>
<input
type="search"
placeholder="Search..."
className="flex-1 outline-none border-none bg-transparent text-white"
defaultValue={search}
name="search"
/>
</form>
);
};
export default SearchForm;
On the step 4, the console.log
prints undefined but the term is still visible on the input. Why is that happening and how to fix that?
All these components are server side components.
Thank you!