Stay state minimal!

Fateh Mohamed 🐢 - Sep 26 - - Dev Community

Not every variable has to be a state entry in your component. Sometimes we have derived or dependent variables on one state variable. (derived state).

For better performance and to avoid extra calculations and bugs, you need to use "derived state."

Lets have an example of fetching items from an API but we need to calculate the number of pages based on the total returned by the response. I have seen many making this mistake ⬇️❌

const Items =() => {
   const rowsPerPage = 10;

   const [response, setResponse] = useState<{items: Item[], total: number}>({items: [], total: 0})
   const [pages, setPages] = useState<number>(0)

   useEffect(() => {
      setPages(Math.ceil(response.total/rowsPerPage))
   }, [response])

   // fetch data and set response logic here

   return (
     // render items and pagination...
   )
}

Enter fullscreen mode Exit fullscreen mode

This lis not good for simple reasons:

  • pages is a derived state, it is tightly related to the data we are fetching. pages state variable makes no sense in our component without our fetched data.
  • Making it a state variable is an extra calculation for our component.
  • pages can be set manually (setPages(99)) which will lead to bugs and inconsistent logic.

✅ The right way to do it to use useMemo for React or computed for Angular to calculate the number of pages base on our only state response

const Items =() => {
   const rowsPerPage = 10;

   const [response, setResponse] = useState<{items: Item[], total: number}>({items: [], total: 0})
   const pages = useMemo(() => {
    return Math.ceil(response.total/rowsPerPage)
   }, [response])

   // fetch data and set response logic here
   return (
     // render items and pagination...
   )
}

Enter fullscreen mode Exit fullscreen mode

✅ Now it is clean, performant and it will allow reusability if you want to abstracting the calculation logic of the derived state.

Good to watch 😉 Don't use effects

. . . . . . . .