mfs
mfs

Reputation: 61

How to troubleshoot my JSX/CSS so that this mess doesn't happen?

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 messMess

It gets even worse when I click the ºF to change into fahrenheit; Mess2

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 Nice

However the mess with the Cs persists:

Mess3

Help!

Upvotes: 1

Views: 46

Answers (1)

helloitsjoe
helloitsjoe

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 °Cs 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

Related Questions