I am an experienced developer but pretty new to React. I wanted to go on my own and build a simple little weather app that updates the image, tempature, and description of each day when you click on the + or - buttons.
I got it to work but I think it is pretty messy and was hoping for some advice. Firstly, is it bad practice to create a state on a component from props passed in by its parent? I know I could set the values within the state but just decided to keep it the way i designed it initially (at first WeatherCard was a stateless component so i was pulling in props either way). However, I could only imagine that there would be a couple instances that this would be applicable...?
Also, I ran into a problem with injecting images, I was trying to use
<img src={'./folder/image.extension'}>
and then update the src but couldn't figure out how to do that, so I made the function getImage() to help me out. Is there a way you guys can think of to update the src of the image so I can get rid of getImage() and just update the state to a string (file path) that the src pulls from?
Lastly I am really baffled about how the description was reacting. The description would update at a different time than the image, which was not what I was expecting. If you look at the code you will see that I had to adjust the if statements in handleClick to a -1 and a +1 to make up for some kind of what seemed to be like a delay. I don't really understand the issue here, but thats how I compensated for it. What are your guys' thoughts?
Overall, I know this is probably some pretty junk code here but I intend on improving it. Will probably start from scratch and maybe it will go better for me but hoping for some advice!
WeatherCard.js
import React, { Component } from 'react';
import sunny from '../img/sunny.png';
import partly from '../img/partly.png';
import cloudy from '../img/cloudy.png';
import rainy from '../img/rainy.png';
class WeatherCard extends Component {
state = {
day: this.props.data.day,
temp: this.props.data.temp,
description: this.props.data.description
}
getImage = () => {
if (this.state.temp >= 95 ) {
return <img src={ sunny } alt="sunny"></img>
} else if (this.state.temp >= 85) {
return <img src={ partly } alt="partly cloudy"></img>
} else if (this.state.temp >= 75) {
return <img src={ cloudy } alt="cloudy"></img>
} else {
return <img src={ rainy } alt="rainy"></img>
}
}
handleClick = (e) => {
if (e.target.innerHTML === '+') {
this.setState(function(prevState, props){
if (this.state.temp >= 94) {
return {description: 'Sunny'}
} else if (this.state.temp >= 84) {
return {description: 'Partly Cloudy'}
} else if (this.state.temp >= 74) {
return {description: 'Cloudy'}
} else {
return {description: 'Rainy'}
}
});
this.setState ({
temp: (this.state.temp+1)
});
} else {
this.setState(function(prevState, props){
if (this.state.temp >= 96) {
return {description: 'Sunny'}
} else if (this.state.temp >= 86) {
return {description: 'Partly Cloudy'}
} else if (this.state.temp >= 76) {
return {description: 'Cloudy'}
} else {
return {description: 'Rainy'}
}
});
this.setState ({
temp: (this.state.temp-1)
});
}
}
render() {
return (
<div className="card">
<div className="card-head">{ this.state.day }</div>
<div className="card-body">
<h1>{ this.state.temp }</h1>
{ this.getImage() }
<p>{ this.state.description }</p>
</div>
<div className="controls">
<div className="upButton" onClick={ this.handleClick }>+</div>
<div className="downButton" onClick={ this.handleClick }>-</div>
</div>
</div>
)
}
}
export default WeatherCard;
App.js
import React, { Component } from 'react';
import WeatherCard from './components/WeatherCard';
class App extends Component {
state = {
data : [
{
day : 'Monday',
temp : 100,
description : 'Sunny'
},
{
day : 'Tuesday',
temp : 100,
description : 'Sunny'
},
{
day : 'Wednesday',
temp : 100,
description : 'Sunny'
},
{
day : 'Thursday',
temp : 100,
description : 'Sunny'
},
{
day : 'Friday',
temp : 100,
description : 'Sunny'
},
{
day : 'Saturday',
temp : 100,
description : 'Sunny'
},
{
day : 'Sunday',
temp : 100,
description : 'Sunny'
}
]
}
renderCards = () => {
return this.state.data.map((card, i) => <WeatherCard key = {i} data = {this.state.data[i]}></WeatherCard>)
}
render() {
return (
<div className="App">
<div className="cards">
{ this.renderCards() }
</div>
</div>
);
}
}
export default App;