Reputation: 61
I have a toggle that changes temperatures from celsius to fahrenheit in a weather app. The code goes like this:
import React, { Component } from "react";
class Temperature extends Component {
state = {
unit: "metrics"
};
imperial = () => {
this.setState({
unit: "imperial",
imperialTemp: Math.round(this.props.temp * (9 / 5) + 32),
imperialMin: Math.round(this.props.temp1 * (9 / 5) + 32),
imperialMax: Math.round(this.props.temp2 * (9 / 5) + 32)
});
};
metrics = () => {
this.setState({
unit: "metrics"
});
};
render() {
if (this.state.unit === "metrics") {
return (
<div>
<div className="temp">
{this.props.temp}ºC |
<span className="fahrenheit" onClick={this.imperial}>
°F
</span>
</div>
<div className="row">
<div className="col">
<div className="min-max">
{this.props.temp1}ºC |
<span className="fahrenheit" onClick={this.imperial}>
°F
</span>{" "}
| {this.props.temp2}ºC |
<span className="fahrenheit" onClick={this.imperial}>
°F
</span>
</div>
</div>
</div>
</div>
);
} else {
return (
<div>
<div className="temp">
{this.state.imperialTemp}
<span className="celsius" onClick={this.metrics}>
ºC |
</span>
ºF
</div>
<div className="row">
<div className="col">
<div className="min-max">
{this.state.imperialMin}
<span className="celsius" onClick={this.metrics}>
ºC |
</span>
ºF | {this.state.imperialMax}
<span className="celsius" onClick={this.metrics}>
ºC |
</span>
ºF
</div>
</div>
</div>
</div>
);
}
}
}
export default Temperature;
The problem is that instead of a clean image I get this mess
It gets even worse when I click the ºF to change into fahrenheit;
Since I'm only adding one current temperature line and one min/max line per condition, why is this happening? Why is it showing two of each? And what's up with the ºCs? Any suggestions of what's going on? Thank you in advance.
UPDATE:
I was rendering the Temperature component twice, that is why the first image is happening. Now it happily shows this
However the mess with the Cs persists:
Help!
Upvotes: 1
Views: 46
Reputation: 6529
Based on the code you posted, it looks like the temp1
and temp2
props are not numbers, and that you're rendering the Temperature
component twice.
It's difficult to know without seeing the parent component however. It would help to update your code with the parent, where you're rendering Temperature
.
The issue °C
s looks like an issue with the celsius
class, it would also help if you posted that code.
Note: You could simplify this code if you toggle the data in state, rather than conditionally rendering 2 almost identical UIs. Something like this:
class Temperature extends Component {
state = {
unit: "metrics",
tempClass: "celsius",
temp: this.props.initialTemp,
tempMin: this.props.initialTemp1,
tempMax: this.props.initialTemp2
};
toggleUnits = () => {
this.setState(prevState => prevState.unit === "metrics" ? {
unit: "imperial",
tempClass: "fahrenheit",
temp: this.toFahrenheit(prevState.temp),
tempMin: this.toFahrenheit(prevState.tempMin),
tempMax: this.toFahrenheit(prevState.tempMax)
} : {
unit: "metrics",
tempClass: "celsius",
temp: this.toCelsius(prevState.temp),
tempMin: this.toCelsius(prevState.tempMin),
tempMax: this.toCelsius(prevState.tempMax)
});
};
toFahrenheit = temp => Math.round(temp * (9 / 5) + 32)
toCelsius = temp => Math.round((temp - 32) * (5 / 9))
render() {
const { temp, tempClass, tempMin, tempMax } = this.state;
return (
<div>
<div className="temp">
{temp}ºC |
<span className={tempClass} onClick={this.toggleUnits}>
°F
</span>
</div>
<div className="row">
<div className="col">
<div className="min-max">
{tempMin}ºC |
<span className={tempClass} onClick={this.toggleUnits}>
°F
</span>{" "}
| {tempMax}ºC |
<span className={tempClass} onClick={this.toggleUnits}>
°F
</span>
</div>
</div>
</div>
</div>
);
}
}
Upvotes: 1