0

I have two components "search" and "Maindata". I am passing the input value from the search component to maindata component where I want to replace the city attribute with the input value(location) in API. but the browser display went blank and the console give an undefined 'city' error, etc. I got stuck in this problem if anyone has a solution?

Here "search" component;

import React , {useState} from "react";
import Maindata from "./Maindata";
import "../Componentstyle/search.css";
export default function Search() {
  const [location, setLocation] = useState();
  <Maindata city={location}/>
  
  return (
    <div className="main">
      <nav className="istclass">
        <form className="form">
          <div className="search">
            <input
              value={location}
              placeholder="search city"
              className="searchbox"
              onChange={(e)=>setLocation(e.target.value)}
            />
            
            <button className="nd" onClick={(e)=>setLocation(e.target.value)}>
              Submit
            </button>
          </div>
        </form>
      </nav>
    </div>
  );
}

Here "Maindata" component;

import React, { useState, useEffect } from "react";
import "../Componentstyle/Main.css";
export default function Maindata(props) {
  const [data, setData] = useState(null);
  
let city = console.log(props.city);
  let weather = async () => {
    const key = "1ab6ef20384db1d7d9d205d609f7eef0";
    await fetch(
      `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}&units=metric&formatted=0`
    )
      .then((response) => response.json())
      .then((actualData) => setData(actualData));
  };
  useEffect(() => {
    weather();
  }, []);

  if (!data) {
    return <div>Loading...</div>;
  }

  const link = `http://openweathermap.org/img/w/${data.weather[0].icon}.png`;

  return (
    <div className="maindata">
      <div className="city">{data.name}</div>
      <div className="temp">{data.main.temp} C</div>
      <div className="icon">
        <img src={link} alt="not found" />{" "}
      </div>
      <div className="feel">feels Like {data.main.feels_like} C</div>
      <div className="wind">Wind {data.wind.speed} Km/hr</div>
      <div className="cloudy">{data.weather[0].main}</div>
      <div className="humidity">humidity {data.main.humidity}%</div>
      <div className="sunrise">
        sunrise :- {new Date(data.sys.sunrise * 1000).toUTCString()}{" "}
      </div>
      <div className="sunset">
        sunset :- {new Date(data.sys.sunset * 1000).toUTCString()}
      </div>
    </div>
  );
}

2 Answers2

0
<Maindata city={location}/>

keep this line of code inside the return

Ram Kishore
  • 204
  • 3
  • 10
0

In your example, there is no meaningful connection between the Search and Maindata components. Meaning Maindata component will not get rendered on the page because it is not in the return statement of the Search component.

The Maindata component as below, is in JSX format, when you use JSX in your code in React, under the hood, React.createElement() method is being called.

Each call to React.createElement returns an object describing what to render to that part of the page. So it makes sense to put the Maindata component in the return statement. That is responsible for rendering the HTML elements from that component when you're loading a page containing that component.

<Maindata city={location}/> // is JSX and should be in the return statement to get rendered on the page and showing the right location
score30
  • 239
  • 1
  • 2
  • 7
  • if I put Maindata component in the return statement it will render twice and still it's not solving my problem. – Ahsan Khalid Oct 30 '22 at 00:33
  • In your `Maindata` component change `let city = props.location` and in your Search component give `location` in state a default value (e.g. Paris). Also, the return statement in `Search` should have `Maindata`. – score30 Oct 30 '22 at 01:26