Home > database >  How to pass the data input from one component into another component?
How to pass the data input from one component into another component?

Time:08-09

Introducing The Problem

I am beginner ReactJS learner developing a simple weather app using OpenWeather API. The app is designed to fetch data from two components: one that returns the current weather of the user input and another one that returns the weather forecast for the next 5 days.

When the city name is typed down into the input field, the following message appears on the console:

GET https://api.openweathermap.org/data/2.5/weather?q=undefined&units=metric&appid=fc8975bd4701139dcd78e2e288cc3807 400 (Bad Request)

I do not know how to pass the data from Search Component into App Component. Seriously, I have tried a lot of alternatives but they have been unsuccessful. There are commented lines of code to show my last try so far.

(ignore ForecastWeather because this component is empty)

I know that all of you are quite busy folks, but I would appreciate the help in a respectful way. Even suggestions about what I have to study (e.g. callBack) are welcome. I've tried this already:

https://stackoverflow.com/questions/56943427/whether-to-save-form-input-to-state-in-onchange-or-onsubmit-in-react

https://sebhastian.com/react-onchange/

The code is forward below:

App.js

import React, { useState } from "react";
import { Api } from "./Api";
import {
  Search,
  CurrentWeather,
  ForecastWeather,
  Footer,
} from "./components/index";
import "./App.css";

function App() {
  const [getCity, setGetCity] = useState();
  const [weatherData, setWeatherData] = useState(null);
  const [forecastData, setForecastData] = useState(null);

  const handleSearchLocation = (dataSearch) => {
    const weatherDataFetch = fetch(
      `${Api.url}/weather?q=${getCity}&units=metric&appid=${Api.key}`
    );
    const forecastDataFetch = fetch(
      `${Api.url}/forecast?q=${getCity}&units=metric&appid=${Api.key}`
    );

    Promise.all([weatherDataFetch, forecastDataFetch])
      .then(async (response) => {
        const weatherResponse = await response[0].json();
        const forecastResponse = await response[1].json();

        setGetCity(dataSearch);
        setWeatherData(weatherResponse);
        setForecastData(forecastResponse);
      })
      .catch(console.log);
  };

  return (
    <div className="App">
      <Search
        searchResultData={handleSearchLocation}
        textPlaceholder="Search for a place..."
      />
      {weatherData && <CurrentWeather resultData={weatherData} />}
      <ForecastWeather resultData={forecastData} />
      <Footer />
    </div>
  );
}

export default App;

Search.jsx

import React, { useState } from "react";

function Search({ textPlaceholder, searchResultData }) {
  const [searchCity, setSearchCity] = useState("");

  //const handlerOnChange = ( event, dataSearch ) => {
  //setSearchCity(event.target.value);
  //setSearchCity(dataSearch);
  //searchResultData(dataSearch);
  //};

  return (
    <div className="componentsBoxLayout">
      <input
        value={searchCity}
        //onChange={handlerOnChange}
        onChange={(event) => setSearchCity(event.target.value)}
        onKeyDown={(event) => event.key === "Enter" && searchResultData(event)}
        placeholder={textPlaceholder}
      />
    </div>
  );
}

export default Search;

CurrentWeather.jsx

import React from "react";

function CurrentWeather({ resultData }) {
  return (
    <div className="componentsBoxLayout">
      <p>{resultData.name}</p>
    </div>
  );
}

export default CurrentWeather;

ForecastWeather.jsx (empty)

import React from 'react';

function ForecastWeather() {
  return (
    <div className="componentsBoxLayout">ForecastWeather</div>
  )
}

export default ForecastWeather;

Api.js

const Api = {
  url: "https://api.openweathermap.org/data/2.5",
  key: "fc8975bd4701139dcd78e2e288cc3807",
  img: "https://openweathermap.org/img/wn",
};

export { Api };

Yippee-ki-yay

CodePudding user response:

You can not use getCity in this function:

const handleSearchLocation = (dataSearch) => {
    const weatherDataFetch = fetch(
      `${Api.url}/weather?q=${getCity}&units=metric&appid=${Api.key}`
    );
    const forecastDataFetch = fetch(
      `${Api.url}/forecast?q=${getCity}&units=metric&appid=${Api.key}`
    );

    Promise.all([weatherDataFetch, forecastDataFetch])
      .then(async (response) => {
        const weatherResponse = await response[0].json();
        const forecastResponse = await response[1].json();

        setGetCity(dataSearch);
        setWeatherData(weatherResponse);
        setForecastData(forecastResponse);
      })
      .catch(console.log);
  };

getCity is defined on that function so it does not exist when you try to use it, unless you need getCity later for another component I would delete it becuase is redundant and do this:

const handleSearchLocation = (dataSearch) => {
    const weatherDataFetch = fetch(
      `${Api.url}/weather?q=${dataSearch}&units=metric&appid=${Api.key}`
    );
    const forecastDataFetch = fetch(
      `${Api.url}/forecast?q=${dataSearch}&units=metric&appid=${Api.key}`
    );

    Promise.all([weatherDataFetch, forecastDataFetch])
      .then(async (response) => {
        const weatherResponse = await response[0].json();
        const forecastResponse = await response[1].json();

        setWeatherData(weatherResponse);
        setForecastData(forecastResponse);
      })
      .catch(console.log);
  };

When you run searchResultData on the search component you send the city you are looking for. Remember that useState will trigger a re-render but a function that is already running before that will never get the new value of the state if the state changes

  • Related