When changing URL need to reset state
Unanswered
Basset Artésien Normand posted this in #help-forum
Basset Artésien NormandOP
This is my search component which is used within a Search page.
When browsing away from /search the text state does not seem to be resetting
When browsing away from /search the text state does not seem to be resetting
'use client'
import React, { useState, useEffect, useRef } from 'react'
import { MagnifyingGlassIcon } from '@heroicons/react/20/solid'
import { useDebounce } from '@web/app/utils/'
import { useRouter, useSearchParams, usePathname } from 'next/navigation'
// TODO fix on button press
function Search() {
const searchParams = useSearchParams()
const search = searchParams.get('query')
const initialRender = useRef(true)
const [text, setText] = useState(search)
const query = useDebounce(text, 750)
const router = useRouter()
useEffect(() => {
setText(search)
}, [search])
useEffect(() => {
if (initialRender.current) {
initialRender.current = false
return
}
if (query) {
router.push(`/search?query=${query}`)
}
}, [query])
return (
<search className="flex flex-row items-center justify-center text-gray-600 px-2 py-3 border-b-[1px] border-zinc-600 md:border-0 ">
<input
className="border-2 border-gray-300 bg-white px-5 pr-16 rounded-full text-sm focus:outline-none md:h-8 h-10"
type="search"
name="search"
placeholder="Search"
onChange={(e) => setText(e.target.value)}
/>
<MagnifyingGlassIcon className="w-5 h-5 text-zinc-500 relative right-10" />
</search>
)
}
export default Search
21 Replies
Basset Artésien NormandOP
you may need to pass a key to the input.
here's a different implementation you can check that doesn't even require state
https://github.com/dayoawobeku/album-colors-app/blob/82aa110459ac62a6509885c3f246a54f6c7fe810/src/components/nav.tsx
here's a different implementation you can check that doesn't even require state
https://github.com/dayoawobeku/album-colors-app/blob/82aa110459ac62a6509885c3f246a54f6c7fe810/src/components/nav.tsx
Basset Artésien NormandOP
looking now
Milkfish
Easiest way is to use the pathname in the key - should reset the component when you navigate away (but beware, also rerenders on every pathname change as well)
Basset Artésien NormandOP
What is the best approach here?
the whole page?
Milkfish
something like
const pathname = usePathname();
<Search key={
search-component-${pathname}
}>You could alternatively do something like:
const isSearchPage = pathname == '/search'
useEffect(() => { setText("") }, [isSearchPage])
Basset Artésien NormandOP
this wont re-render?
Milkfish
which one, key or the useeffect?
Basset Artésien NormandOP
i know the useEffect will
not fully sure how the key works
export default function NavBar() {
return (
<header className="flex items-center justify-between dark:bg-zinc-800">
<FilmIcon className="h-7 w-7 text-slate-200 m-2" />
<input className="side-menu" type="checkbox" id="side-menu" />
<label className="hamb" htmlFor="side-menu">
<span className="hamb-line"></span>
</label>
<nav className="nav">
<Search />
<Navigation navItems={navItems} />
</nav>
</header>
)
}
this is where search is implemented
which in turn is in the root layout:
import Navbar from '@web/app/ui/main/Navbar'
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="grid grid-rows-[50px_1fr] w-screen h-screen overflow-hidden">
<Navbar />
<main className="dark:bg-zinc-700 overflow-y-scroll">{children}</main>
</div>
)
}
Milkfish
useEffect is arguably the most efficient method, and yes will cause rerender - but your component is already rerendering everytime there is a change because your using the usePathname, useSearchParams hooks
Basset Artésien NormandOP
hm the useEffect does not seem to work
Basset Artésien NormandOP
man im dumb. dont i just need
value={text || ''}
in the JSX