I have a query parameter like this:
const router = useRouter()
const { name } = router.query
I want to use this name
and pass it to a value that has state:
const [queryName, setQueryName] = useState('')
The issue is I cannot pass it as the default, like this: useState(name)
because the name
updates.
So rather than using the name
as the default value I'd have to set it.
setQueryName(name)
This however is also not valid, I can't just set it within the component like this.
So I'd have to use useEffect
useEffect(() => {
setQueryName(name)
}, [name])
However this is triggering a infinite error:
Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
What is the correct way to set state from another hook?
CodePudding user response:
Turns out I was pulling the prop from the router and doing some manipulation, I wrapped this logic in a memo and it works.
const useName = (): ComponentBlock | null => {
const router = useRouter()
return useMemo(() => {
const { name } = router.query
if (name && typeof name === 'string') {
return name
}
return null;
}, [router])
}
and
const queryName = useName()
const [name, setName] = useState('')
useEffect(() => {
setName(name)
}, [name])
CodePudding user response:
You can use useLocation() hook in react router v5
const search = useLocation().search;
const name = new URLSearchParams(search).get('name');
const [value, setValue] = useState(name);
CodePudding user response:
There is a little trick you could do.
And I imagine it would make the code more readable. The value you receive from url is used as initial value and it can be changed later by some UI in the page, right?
const router = useRouter();
const { name: initialName } = router.query; // get name, but we'll be calling it "initialName" onward.
const [name, setName] = useState(initialName);