Internal implementation of “makeStyles” in React Material-UI?

High-level picture of inputs/outputs/side effects

makeStyles

  • overview: This function is typically called at the top-level within a JavaScript file (not from within a component/function), and it returns a function (typically called useStyles) that will be used from within a function component.
  • input: styles object or styles object creator function
    • If the input is an object, it is assumed that each property of the object defines a style rule. The property name is the rule name and the property value is an object with CSS properties and/or nested rules. Each style rule will later be used to generate a CSS class.
    • If the input is a function, it is assumed to be a function that receives the theme as an argument and then returns a styles object with the structure described in the case where the input is an object.
    • In the makeStyles function declaration, this input is called stylesOrCreator. This is then normalized by the getStylesCreator function to be an object with a create property that points at a function which will return a styles object.
  • output: useStyles function
    • The function returned by makeStyles is typically called useStyles and is a custom hook. This means that it can only be called from within a function component and must be called unconditionally.
    • At the point of returning this useStyles function, very little has happened. The function knows about its stylesCreator, but hasn’t used it yet. Via the stylesCreator’s options, the useStyles function knows an index that will later be used to determine the location in the <head> of the style sheet for these styles relative to the other style sheets generated by other calls to makeStyles/useStyles.
  • side effect: increments a global counter that is used to determine the index within the <head> of style sheets generated by makeStyles/useStyles.

useStyles

  • overview: This is the function returned by makeStyles. It should be called from within a function component to get a classes object described below.
  • optional input: props object
  • output: classes object
    • This object maps each style rule name in your styles object to a generated CSS class name. You can then leverage classes.rulename in your component rendering to apply that CSS class to an element.
  • side effect: Adds a style sheet to the DOM in the <head> containing a CSS class per style rule.

Where the main work occurs

The bulk of the magic happens when you call the useStyles function. The beginning of the function is here. Here are the key steps it performs:

  • Calls attach. The attach function does the following key steps:
    • Calls stylesCreator.create to get your styles object.
    • Leverages JSS to create a style sheet based on your styles object. It is also within here that JSS generates the class names that will be in the classes object.
    • Attaches this style sheet to the DOM at the appropriate location within the <head>.
  • Returns the classes object
  • If something happens to trigger re-creating the CSS or if the component unmounts, then detach is called to remove the previously generated style sheet.

Leave a Comment