I am not able to make a React hooks toggle button to change between celcius and farenheit?

I want to toggle between Celcius and Fahrenheit with an onClick button on °C which can convert to Fahrenheit for my main.temp value max_temp and min_temp at the same time.

Weather.js

import React, { useState, useEffect } from 'react';
import Homepage from './Homepage';

function Weather() {
  const API_KEY = 'b78ffacf63ad995ef34f6811b0e06433';
  const [localweather, setLocalweather] = useState([]);
  const [query, setQuery] = useState("");

  //geolocation to get the local weather
  const getLonLat = () => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition((position) => {
        const lon = position.coords.longitude;
        const lat = position.coords.latitude;
        fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&units=metric&appid=${API_KEY}`)
          .then(response => response.json())
          .then(result => {
            setLocalweather(result)
            return;
          })
          .catch(err => console.log(err));
      })
    }
  }

  useEffect(() => {
    getLonLat();
  }, [])

  //give input to get other location weather
  const searchInput = (e) => {
    e.preventDefault()
    fetch(`https://api.openweathermap.org/data/2.5/weather?q=${query}&units=metric&appid=${API_KEY}`)
      .then(response => response.json())
      .then(result => {
        setLocalweather(result)
        setQuery("")
      })
      .catch(err => console.log(err));
  }

  return (
    <Homepage
      localweather={localweather}
      getLonLat={getLonLat}
      searchInput={searchInput}
      setQuery={setQuery} />
  )

}
export default Weather;

Homepage.js

import React, { useState } from 'react';
function Homepage(props) {
  return (
    <div>
      <h3>{props.localweather.main && props.localweather.main.temp} °C</h3>
      <span>{props.localweather.main && props.localweather.main.temp_min} °C</span>
      <span>{props.localweather.main && props.localweather.main.temp_max} °C</span>
    </div>
  )
}

export default Homepage;

Hey @n3tspid3r, what have you tried so far?

In your code I don’t see any button or C/F hook.

[EDIT]
In the meantime I wen ahead and made a small demo with a value and a button to toggle C/F

It’s very basic and the code can be arranged better, but I hope it suffice a demonstration purpose

@Marmiz Sorry, I have deleted what I tried but I am facing the same problem even after trying your code. The temperature value that I get from the API shows undefined when I put it on the state.

weather.js file

import React, { useState, useEffect } from 'react';
import Homepage from './Homepage';

function Weather() {
    const API_KEY = 'b78ffacf63ad995ef34f6811b0e06433';
    const [localweather, setLocalweather] = useState([]);
    const [query, setQuery] = useState("");
    const [temp, setTemp] = React.useState(localweather.main && localweather.main.temp);
    const [unit, setUnit] = React.useState("C");
console.log(temp)
    //geolocation to get the local weather
    const getLonLat = () => {
        if(navigator.geolocation) {
            navigator.geolocation.getCurrentPosition((position) => {
                const lon = position.coords.longitude;
                const lat = position.coords.latitude;
                fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&units=metric&appid=${API_KEY}`)
                    .then(response => response.json())
                    .then(result => {
                        setLocalweather(result)
                        return;
                    })
                    .catch(err => console.log(err));
            })
}
}

useEffect(() => {
    getLonLat();
}, [])

    //give input to get other location weather
    const searchInput = (e) => {
        e.preventDefault()
        fetch(`https://api.openweathermap.org/data/2.5/weather?q=${query}&units=metric&appid=${API_KEY}`)
            .then(response => response.json())
            .then(result => {
                setLocalweather(result)
                setQuery("")
            })
            .catch(err => console.log(err));
    }

    const oppositeUnit = unit === "C" ? "F" : "C";

    const convert = () => {
        if (unit === "C") {
            const newT = temp * 1.8 + 32;
            setTemp(Math.round(newT));
            setUnit(oppositeUnit);
        }

        if (unit === "F") {
            const newT = ((temp - 32) * 5) / 9;
            setTemp(Math.round(newT));
            setUnit(oppositeUnit);
        }
    };
    return (
        <Homepage 
        localweather={localweather}
        getLonLat={getLonLat} 
        searchInput={searchInput} 
        setQuery={setQuery}
        convert={convert}
        oppositeUnit={oppositeUnit}
        temp={temp}
        unit={unit}
        />
    )

}
export default Weather;

Homepage.js file

import React  from 'react';
function Homepage(props) {
    return (
 <div>
            <p>
                Temperature {props.temp} {props.unit}
            </p>
            <button onClick={props.convert}>Convert to {props.oppositeUnit}</button>
            <span className="value">{props.localweather.main && props.localweather.main.temp_min} °C</span>
            <span className="value">{props.localweather.main && props.localweather.main.temp_max} °C</span>
        </div>
    )
}

export default Homepage;

I’m confused on your data shape, you declare your local weather as an array, but then try to read from it as if it were an object.

Yes i did some silly mistakes but at the end i got it working right. Thanks @Marmiz for the help . Your code helped me to figure out the problem.

1 Like