Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typed props when using Material UI makeStyles

I'm trying to migrate some of my React components to the new makeStyles/useStyles hook API from Material UI. If I understand correctly I can keep accepting classes as a prop from parent components as long as I pass the props to useStyles:

const MyComponent = (props: Props) => {
  const { myProp } = props;
  const classes = useStyles(props);

I was wondering how to declare my Props type in that case. The equivalent with the HOC API being:

const styles = createStyles({
  a: {},
  b: {}
});

interface Props extends WithStyles<typeof styles> {
  myProp: string;
}

Here is something that works but looks a bit verbose:

const styles = createStyles({
  a: {},
  b: {}
});

interface Props extends StyledComponentProps<ClassKeyOfStyles<typeof styles>> {
  myProp: string;
}

const useStyles = makeStyles(styles);

Is there a better way? Ideally without the need for createStyles and using makeStyles inline with the styles declaration.

like image 890
Such Avatar asked May 27 '19 12:05

Such


1 Answers

To know at compile time which properties/classes were declared, I used such workaround.

import React from 'react';
import { Theme, makeStyles } from '@material-ui/core';
import { BaseCSSProperties } from '@material-ui/core/styles/withStyles';

interface StyleProps {
    root: BaseCSSProperties,
}

type PropsClasses = Record<keyof StyleProps, string>

let baseStyle: StyleProps = {
    root: {
        color: "red",
    },
};

const useStyles = makeStyles<Theme, StyleProps>(() => baseStyle as any);

const MyComponent = () => {
    const classes: PropsClasses = useStyles({} as StyleProps);
    return (<div className={classes.root}>This is root!</div>)
}

export default MyComponent;

Key moment here - do not forget to declare type for the classes constant.

You can reuse this types in other components and have all required information.

like image 113
ydanila Avatar answered Oct 04 '22 09:10

ydanila