Search code examples
reactjsreact-hooksgetelementbyidweatherinnertext

Unhandled Rejection (TypeError): Cannot set property 'innerText' of null in React-hooks


I want to make a weather app. But the string does not appear on the component I want.

How can innerText be used in React?

This is my Weather.jsx

import React from "react";

const Weather = () => {
  const API_KEY = '123456789';
  const COORDS = "coords";
  const weather = document.getElementById("weather");

  const getWeather = (lat, lng) => {
    fetch(
      `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${API_KEY}&units=metric`
    )
      .then(function (response) {
        return response.json();
      })
      .then(function (json) {
        const temperature = json.main.temp;
        const place = json.name;
        weather.innerText = `${temperature}℃,\n ${place}`;
      });
  };
};
export default Weather;

This is the screen code for the weather to appear.

import React from "react";
import styled from "styled-components";
import Weather from "../../Components/Weather";

const DetailPresenter = () => {
  
  return (
    <>
      <DetailContainer>
        <div id="weather">{Weather()}</div>  
      </DetailContainer> 
    </>
  );
};
export default DetailPresenter;

Solution

  • This isn't how react renders UI. We don't invoke the functions directly, we render them into the JSX "template" for React to invoke when necessary. Nothing is invoking your getWeather function to actually fetch the weather data. Also, direct DOM manipulation is an anti-pattern in react.

    1. Save the text you want displayed into local component state.
    2. Render it. Your Weather component currently returns undefined, which isn't valid for React, components must return valid JSX.

    Weather

    const Weather = () => {
      const API_KEY = '123456789';
      const COORDS = "coords";
      const [weather, setWeather] = React.useState('');
    
      const getWeather = (lat, lng) => {
        fetch(
          `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${API_KEY}&units=metric`
        )
          .then(function (response) {
            return response.json();
          })
          .then(function (json) {
            const temperature = json.main.temp;
            const place = json.name;
            setWeather(`${temperature}℃,\n ${place}`);
          });
      };
    
      React.useEffect(() => {
        getWeather(......lat & long);
      }, []); // <-- run effect once on component mount
    
      return weather; // <-- string is valid JSX
    };
    

    DetailPresenter

    import React from "react";
    import styled from "styled-components";
    import Weather from "../../Components/Weather";
    
    const DetailPresenter = () => {
      
      return (
        <DetailContainer>
          <Weather /> // <-- render component, don't invoke
        </DetailContainer> 
      );
    };