I was given a task of optimizing our dashboards performance this week. And to be honest I wasn't really sure what is it means by optimization. On googling I found that one way to optimize is reducing unnecessary re-render and aviding unnecessary API calls.
so I set the my goals like this:
To have Fewer Render hence better performance (possibly by introducing useRef instead of useState if possible)
Eliminating Unnecessary API calls (when applying the same filter or when clicking reset again and again shouldn't trigger an API call)
Right way to use useReducer and check for anti-patterns in my
custom hook
And I came up with the minimal, workable example and here is the working demo
I was only half successful in acheiving my optimization:
- Once I apply filter and then apply it again it doesn't call the mock api
- Once I change resultLimit to same value it doesn't call api Here is how I did it
const [page,setPage] = useState(1)//current page filter
const [resultLimit,setResultLimit] = useState(10) //result limit filter,currently not implemented
const [totalCount,setTotalCount] = useState(0) // total result count filter
const [filters,setFilters] =useState<IFilterBugData>({
platform:[],
rootCause: [],
reportedBy: [],
assignedTo: [],
status: [],
defectCategory: [],
severity: [],
priority: [],
})//filter options
const [bugsData,setBugsData] = useState<IBug[]>([]) //bugs result
const handleFilterDispatch = (state:IKeyValue[],payload:IFilterPayload) => {
let _temp = [...state]
switch(payload.action){
case 'add':
return _temp
case 'reset':
return []
default:
return _temp
}
}// use reducer for handling function temp filter state
// const filterState = useRef<IKeyValue[]>([])
const [filterState,filterDispatch] = useReducer(handleFilterDispatch,[])//temp filter state
const [finalFilterState,setFinalFiterState] = useState<IKeyValue[]>([])//input filter state
const memoizedInput:IInputBugData = useMemo(() => {
return {
filters:finalFilterState,
page,
resultLimit
}
},[finalFilterState,page,resultLimit])
const getBugsData = useCallback(() => {
console.log('inside memoized callback',memoizedInput)
return getBugs(memoizedInput)
}, [memoizedInput])
and calling the memoized function getBugsData
in useEffect although I have doubt that memoizedInput
is not necessary here
useEffect(() => {
console.log('rendering dataaaaaa')
let {resultCount,currentPage,bugs,filters} = getBugsData()
setBugsData(bugs)
setFilters({...filters})
setPage(currentPage)
setTotalCount(resultCount)
},[getBugsData])
But What it failed to do is
- It stills call api when I deselect and select the same option resulting in same filterstate
- clicking reset always calls api (even if there is no filter applied)
- even if I haven't changed my filters when I click apply it re-renders (only once)
so my question is how would you guys do it differently.
Note: you guys can also point out the anti-patterns I have done, as I am not sure if I am doing custom hooks or useReducer/useCallback/useMemo the correct way
Top comments (0)