DEV Community

Cover image for Stay state minimal!
Fateh Mohamed 🐒
Fateh Mohamed 🐒

Posted on

Stay state minimal!

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

Top comments (1)

Collapse
 
alaindet profile image
Alain D'Ettorre

Yes, derived state is crucial for all frameworks (and libraries) and yes, useMemo() is the correct equivalent of Angular's computed(), which is very close to Preact's computed() as well as Vue's computed properties.

But in React, if the state comes just from a prop, you can simply calculate derived state straight away, there's no need for useMemo().