React Hook "useStyles" is called in function which is neither a React function component or a custom React Hook function

Viewed 6348

As per the title, I am getting the following error message when implementing Material UI with React.

React Hook "useStyles" is called in function "appBar" which is neither a React function component or a custom React Hook function

I have reviewed the rules of hooks (https://reactjs.org/docs/hooks-rules.html) and I am not sure what I have missed. Any assistance rendered would be appreciated.

Here is my source code:

import React from 'react';
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      flexGrow: 1,
    },
    menuButton: {
      marginRight: theme.spacing(2),
    },
    title: {
      flexGrow: 1,
    },
  }),
);

export default function appBar() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <AppBar position="static">
        <Toolbar>
          <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" className={classes.title}>
            News
          </Typography>
          <Button color="inherit">Login</Button>
        </Toolbar>
      </AppBar>
    </div>
  );
}
2 Answers

Try renaming your component with PascalCase.

eslint-plugin-react-hooks thinks that your function component is not a function component because it doesn't start with a capital letter.

Note: the react docs state that user-defined components must be capitalized before their use in JSX to avoid being treated as HTML elements.

In the example below I've named the component AppBarWrapper because the name AppBar is already being used by the component imported from @material-ui/core/AppBar.

import React from 'react';
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      flexGrow: 1,
    },
    menuButton: {
      marginRight: theme.spacing(2),
    },
    title: {
      flexGrow: 1,
    },
  }),
);

export default function AppBarWrapper() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <AppBar position="static">
        <Toolbar>
          <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" className={classes.title}>
            News
          </Typography>
          <Button color="inherit">Login</Button>
        </Toolbar>
      </AppBar>
    </div>
  );
}

First install:

npm install @material-ui/styles 

Second: read documentation

" Getting started There are 3 possible APIs you can use to generate and apply styles, however they all share the same underlying logic."

Hook API

Related