I'm trying to use material UI in my class component, instead of converting everything to Hooks. I'm not sure which method is easier, Hooks or retro-fitting what I have.
https://material-ui.com/styles/basics/#higher-order-component-api
Here's my code:
class App extends Component {
constructor(props) {
super(props);
this.state = {
hits: [],
desc: [],
};
}
componentDidMount() {
this.fetchData();
}
fetchData() {
fetch(
`https://api.openweathermap.org/data/2.5/onecall?lat=30.2672&lon=-97.7431&units=imperial&exclude=minutely&appid=${process.env.REACT_APP_WEATHER_KEY}`
)
.then((json) => json.json())
.then((data) => {
this.setState({
hits: data.current,
desc: data.current.weather[0],
});
console.log(data);
})
.catch((error) => console.log("parsing failed", error));
}
render() {
const useStyles = makeStyles({
root: {
maxWidth: 450,
margin: "0 auto",
},
MuiCardContent: {
padding: 0,
"&:last-child": {
paddingBottom: 2,
},
},
title: {
fontSize: 14,
},
});
const unixTimestamp = this.state.hits.sunset * 1000;
const date = new Date(unixTimestamp);
const localized = date.toLocaleString();
const classes = useStyles();
return (
<Card className={classes.root} variant="outlined">
<CardContent className={classes.MuiCardContent}>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
Current Weather
</Typography>
<Typography variant="subtitle1" component="h2">
<div>{this.state.desc.main}</div>
<div>Temp: {this.state.hits.temp} F</div>
<div>Feels Like: {this.state.hits.feels_like} F</div>
<div>Humidity: {this.state.hits.humidity}%</div>
<div>Sunset: {localized}</div>
<div>UV Index: {this.state.hits.uvi} (Take caution when above 8)</div>
</Typography>
</CardContent>
</Card>
);
}
}
export default App;
I looked at the material-ui docs, but I'm confused on how to implement this inside of a class component. I'm new to hooks so that seems a bit crazy right now.
In your case, if you want to style your class component, you should use withStyles.
Try this:
import React, { Component } from 'react'; import { withStyles } from '@material-ui/core/styles'; const useStyles = (theme) => ({ root: { paddingTop: theme.spacing(8), backgroundColor: "white" }, }) class App extends Component { render() { const { classes } = this.props return( <div className = {classes.root}>... </div> ); } } export default withStyles(useStyles)(App);
makeStyles
returns a hook that is only valid with functional components. You've correctly found the withStyles
HOC, but you just need to use it. Factor out and externally define your style object, and pass to the withStyles()
HOC.
...
import { withStyles } from '@material-ui/core/styles'; // <-- import withStyles HOC
...
const styles = {
root: {
maxWidth: 450,
margin: "0 auto",
},
MuiCardContent: {
padding: 0,
"&:last-child": {
paddingBottom: 2,
},
},
title: {
fontSize: 14,
},
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
hits: [],
desc: [],
};
}
componentDidMount() {
this.fetchData();
}
fetchData() {
fetch(
`https://api.openweathermap.org/data/2.5/onecall?lat=30.2672&lon=-97.7431&units=imperial&exclude=minutely&appid=${process.env.REACT_APP_WEATHER_KEY}`
)
.then((json) => json.json())
.then((data) => {
this.setState({
hits: data.current,
desc: data.current.weather[0],
});
console.log(data);
})
.catch((error) => console.log("parsing failed", error));
}
render() {
const unixTimestamp = this.state.hits.sunset * 1000;
const date = new Date(unixTimestamp);
const localized = date.toLocaleString();
const { classes } = this.props; // <-- destructure injected classes prop
return (
<Card className={classes.root} variant="outlined">
<CardContent className={classes.MuiCardContent}>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
Current Weather
</Typography>
<Typography variant="subtitle1" component="h2">
<div>{this.state.desc.main}</div>
<div>Temp: {this.state.hits.temp} F</div>
<div>Feels Like: {this.state.hits.feels_like} F</div>
<div>Humidity: {this.state.hits.humidity}%</div>
<div>Sunset: {localized}</div>
<div>UV Index: {this.state.hits.uvi} (Take caution when above 8)</div>
</Typography>
</CardContent>
</Card>
);
}
}
export default withStyles(styles)(App); // <-- decorate App with classes prop
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.