Reputation: 6586
I have two React components in a Create React App app, a parent component (App.js) and a child (QuoteMachine.js).
I applied the withStyles
HOC API successfully in App.js, but when I used the same format to add one in QuoteMachine.js, passing this.props.classes.card
as a property to the Material-UI Card component instance caused a TypeError Cannot read property 'props' of undefined.
Is there a problem with having the withStyles
HOC in multiple components? Should I use a ThemeProvider
instead?
QuoteMachine.js:
import React from 'react';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import './QuoteMachine.css';
import { withStyles } from '@material-ui/core/styles';
const styles = {
card: {
padding: '30px'
}
};
// Parentheses around function body is implicit return
const QuoteMachine = (props) => (
<Card className={this.props.classes.card}>
<CardContent>
{props.isDoneFetching ?
(
<Typography>
<p className="quote">{props.randomQuote().quote}</p>
<p className="author">–{props.randomQuote().author}</p>
</Typography>
) : 'Loading...'}
</CardContent>
<CardActions>
<Button
size="large"
onClick={props.nextRandomQuote}
>
Next
</Button>
</CardActions>
</Card>
)
export default withStyles(styles)(QuoteMachine);
App.js:
import React, { Component } from 'react';
import QuoteMachine from './QuoteMachine';
import 'typeface-roboto'; // From Material-UI
import { Grid } from '@material-ui/core';
import { withStyles } from '@material-ui/core/styles';
import backgroundImage from './dawn.jpg';
const styles = {
// container is root component (set in Grid component instance)
container: {
display: 'flex',
alignItems: 'center',
height: '100vh',
background: `url(${backgroundImage}) center`,
backgroundSize: 'cover', // Using this in background causes issues
}
};
class App extends Component {
constructor(props) {
super(props);
...
}
....
render() {
return (
<Grid
id="quote-box"
className={this.props.classes.container}
justify="center"
container
>
<Grid xs={11} lg={8} item>
<QuoteMachine
isDoneFetching={this.state.isDoneFetching}
randomQuote={this.randomQuote}
nextRandomQuote={this.nextRandomQuote}
/>
</Grid>
</Grid>
);
}
}
export default withStyles(styles)(App);
Upvotes: 0
Views: 2439
Reputation: 281616
Since QuoteMachine
is a functional component, it doesn't have a this
instance and the props are available from the argument to the functional component. You would access the classes like
<Card className={props.classes.card}>
Upvotes: 2