Problem
I have a custom hook which is used for updating the query string in the url with the help of location and history from 'react-router-dom'. So in the components whenever I want to add a new query I use this hook. In this custom hook I used useRef to avoid updating the custom hook so that the component using the hook will not render, but components using this hooks are rendered every time the location is changed.
Custom hook to update query string in the url
import { useRef } from 'react'
import { useHistory, useLocation } from 'react-router-dom'
export const useUpdateQueryString = () => {
const history = useHistory()
const location = useLocation()
const routerRef = useRef({ search: '', pathname: '' })
useEffect(() => {
routerRef.current = { pathname: location.pathname || '', search: location.search || '' }
}, [location.pathname, location.search])
const onUpdateQueryString = useCallback((newQueryObj) => {
const newQueryParamString = setQueryStringValue(newQueryObj, routerRef.current.search)
history.push(`${routerRef.current.pathname}${newQueryParamString}`)
}, [])
return {
onUpdateQueryString
}
}
Component which uses this hook
import React, { useCallback } from 'react'
import { getTestQueryObj, useTestQueryString } from 'utils/query-string'
const TestComponent: React.FC = () => {
const { onUpdateQueryString } = useTestQueryString()
const handleClick = useCallback(() => {
onUpdateQueryString(getTestQueryObj())
}, [])
console.log('TestComponent rendered')
return <div onClick={handleClick}>{'Hello Component'}</div>
}
export default React.memo(TestComponent)
Note: getQueryObj is a function which gets the query obj and setQueryObj is a another function which takes the query obj and returns a string