Archimedes Trajano
Archimedes Trajano

Reputation: 41220

How do I use other React hooks inside a React useMemo hook function?

I was thinking of optimizing some code as the results can be cached since it only needs to iterate through the data once. In my case it's determining the colors and font styles for a specific set of components for Native Base.

Presently I useTheme() to get the theme data. So I thought I can simply go from

function useTextStyle(component: string) : TextStyle {
  const theme = useTheme();
  const colorMode = useColorMode();
  return computeTextStyles(component, colorMode);
}
function useTextStyles() : StyleSheet.NamedStyle<{header1:TextStyle,body:TextStyle}> {
  return {
    header1: useTextStyle('Heading');
    body: useTextStyle('Text');
  }
}

to

function useTextStyles() {
  const colorMode = useColorMode();
  return useMemo(()=> ({
    header1: useTextStyle('Heading');
    body: useTextStyle('Text');
  }), [colorMode])
}

But that gives a warning saying I shouldn't use hooks in useMemo.

Upvotes: 1

Views: 2582

Answers (1)

Kieran Osgood
Kieran Osgood

Reputation: 968

(Without being preachy I promise) I would first ask whether this is a needed adjustment - unless theres a noticeable performance dip I wouldn't bother. Ultimately none of this should change unless the colorMode is changing by the looks of things, and it can be a bad thing when things are being over-optimised (useMemo does have a cost associated with calling it, which may or may not outweigh the benefit of the memoization). Best to use the chrome debugger to see if it actually changes things after, if not faster then it's probably best left unoptimised for the sake of the next develop trying to figure out whats going on).

However! If you deem it is necessary, then the problem is in the useTextStyle within the memo portion.

I would personally be more inclined to write it as:

function useTextStyles() : StyleSheet.NamedStyle<{header1:TextStyle,body:TextStyle}> {
  // const theme = useTheme(); // Is this even used?
  const colorMode = useColorMode();

  return useMemo(()=> ({
    header1: computeTextStyles('Heading', colorMode);
    body: computeTextStyles('Body', colorMode);
  }), [colorMode])
}

Either way you still need to call the compute functions on all of the entries, and this way you are only just calling the useColorMode once and passing the value along, and the only dependency is to be the colorMode, (and computeTextStyle)

Upvotes: 1

Related Questions