jan
jan

Reputation: 255

Making a Materal UI card template in react

I'm trying to make a card template in React using Material UI. I need this template so I can easily generate more cards in the future. The documentation often have the script in one single file, and never explain how to separate it and still having it to work. I don't gonna use the export import lines here just to simplify the code.

Lets say i have a Cardtemplate.jsx

const useStyles = makeStyles({
  root: {
    maxWidth: 345,
  },
  subtitle: {
    fontSize: 14,
  },
  card:{
    height: 100,
  }
  title:{
    fontSize: 12,
  }
});




const Cardtemplate = ({ classes, image, title, subtitle }) => {
  
  return (
    
      <Card className={classes.card}>
        <CardMedia image={image} />
         <Typography className={classes.title} variant={'h2'}>{title}</Typography>
          <Typography className={classes.subtitle}>{subtitle}</Typography>
        </Card>
   
  );
};

export default Cardemplate;

Then I want to use the temple to generate card1.jsx

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

  return (
    <Cardtemplate
      classes={styles}
      title={'Some title'}
      subtitle={'some subtitle'}
      image={'image.png'}
    />
  );
} 

Finally in the App.js I would render all the cards like this.

function App(){
  return(
   <Card1 />
   <Card2 />
   <Card3 />
   ...
   ...
 )
};

The problem is that I getting syntaxError telling that Identifier 'useStyles' has already been declared or some undefined properties is missing. I have tried to place the const classes = useStyles(); in the cardTemplate.jsx.

I have also tried to wrap the const useStyles inside the const Cardtemplate function just to make sure that the useStyles also get exported, but all I get Is errors. There's something I have been missing here. How can I do this the proper way without any further errors?

Upvotes: 0

Views: 409

Answers (1)

Renan Souza
Renan Souza

Reputation: 915

Your CardTemplate shouldn't receive classes from props, it should be declared on it, using the useStyles defined above, so it should look like this:

const useStyles = makeStyles({
  // style
});

export default function CardTemplate({ title, subtitle }) {
  const classes = useStyles();

  return (
    <Card className={classes.card}>
      <Typography className={classes.title} variant={"h2"}>
        {title}
      </Typography>
      <Typography className={classes.subtitle}>{subtitle}</Typography>
    </Card>
  );
}

Then, you can have each of your Cards importing this component and reusing, per example:

// Card1.js
export default () => {
  return <CardTemplate title="Card 1" subtitle="The First" />;
};

// Card2.js
export default () => {
  return <CardTemplate title="Card 2" subtitle="The Second" />;
};

// Card3.js
export default () => {
  return <CardTemplate title="Card 3" subtitle="The Third" />;
};

Lastly, you can render them in any place as you seem fit, example:

ReactDOM.render(
  <>
    <Card1 />
    <Card2 />
    <Card3 />
  </>,
  document.querySelector("#root")
);

There is a running code sandbox I made for you. You can check it here!

Upvotes: 1

Related Questions