I want to transfer a variable from search component as "child" to API component as "Parent". I did it with event for another part of codes but I don't know how did work exactly for a variable on my codes. I want send "apiUrl" to parent. When user click on "current" get new location and generate new apiUrl, then send it to parent component for other stuff
Child:
import React from "react";
import "./Search.css";
const Search = function (props) {
const handleChange = (event) => {
props.onchange(event.target.value);
};
const handleSubmit = (event) => {
event.preventDefault();
props.onsubmit(event.target.value);
};
const navigation = (event) => {
event.preventDefault();
navigator.geolocation.getCurrentPosition(showPosition);
};
const showPosition = (position) => {
let latitude = position.coords.latitude;
let longitude = position.coords.longitude;
let latandlon = `lat=${latitude}&lon=${longitude}`;
let apiKey = "23422500afd990f6bd64b60f46cf509a";
let unit = "metric";
let apiUrl = `https://api.openweathermap.org/data/2.5/weather?${latandlon}&appid=${apiKey}&units=${unit}
`;
};
return (
<form className="form" onSubmit={handleSubmit}>
<div className="input-group">
<input
type="search"
className="form-control me-1"
placeholder="Enter City Name"
aria-label="City Name"
aria-describedby="basic-addon2"
onChange={handleChange}
/>
<div className="input-group-append">
<button className="btn btn-outline-secondary me-1" type="submit">
Search
</button>
<button
className="btn btn-outline-secondary me-1"
type="button"
onClick={navigation}
>
Current
</button>
</div>
</div>
</form>
);
};
export default Search;
Parent:
import React, { useState, useEffect } from "react";
import axios from "axios";
import Search from "./Search";
import ShowCurrentLocation from "./ShowCurrentLocation";
import HumidityAndWind from "./HumidityAndWind";
import CurrentStatus from "./CurrentStatus";
import ShowCurrentDay from "./ShowCurrentDay";
import CurrentDegree from "./CurrentDegree";
const Api = function (props) {
let [searchcity, setSearchcity] = useState("Tehran");
const [value, setValue] = useState("");
const [loader, setLoader] = useState(false);
const [weatherdata, setWeatherdata] = useState("");
const onchange = (data) => {
setValue(data);
};
const onsubmit = () => {
setSearchcity(value);
searchcity = value;
callApi();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(callApi, []);
function callApi() {
const apiKey = "23422500afd990f6bd64b60f46cf509a";
let units = "metric";
let apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${searchcity}&appid=${apiKey}&units=${units}`;
return axios.get(apiUrl).then(getWeatherData);
}
function getWeatherData(response) {
setWeatherdata({
temprature: Math.round(response.data.main.temp),
humidity: response.data.main.humidity,
wind: response.data.wind.speed,
description: response.data.weather[0].description,
city: response.data.name,
country: response.data.sys.country,
});
setLoader(true);
}
if (loader) {
return (
<div>
<div className="row">
<div className="col-md-9">
<Search
data1={searchcity}
onsubmit={(event) => {
onsubmit(event);
}}
data2={value}
onchange={(event) => {
onchange(event);
}}
/>
</div>
<div className="col-md-3 my-auto text-center">
<ShowCurrentLocation
data1={weatherdata.city}
data2={weatherdata.country}
/>
</div>
</div>
<div className="row my-auto">
<div className="col-md-7 my-auto">
<div className="row ">
<div className="col-6 my-auto text-start">
<div>
<HumidityAndWind
data1={weatherdata.humidity}
data2={weatherdata.wind}
/>
</div>
</div>
<div className="col-6 my-auto text-center">
<div>
<ShowCurrentDay />
</div>
</div>
</div>
</div>
<div className="col-md-5 my-auto">
<div className="row">
<div className="col-6 my-auto text-center">
<div>
<CurrentStatus data={weatherdata.description} />
</div>
</div>
<div className="col-6 my-auto text-center">
<CurrentDegree data={weatherdata.temprature} />
</div>
</div>
</div>
</div>
</div>
);
} else {
return "Loader";
}
};
export default Api;
CodePudding user response:
You can't pass data or variable from your children to parent. But you can create some function from parent
and pass it into a child
that you want and the function is receive parameter for passing your data from children to parent. You can use useState to if you want, and pass that into your children component.
Example using useState:
ParentComponent
import { useState } from "react";
import ChildrenComponent from "./ChildrenComponent";
const ParentComponent = () => {
const [dataFromChild, setDataFromChild] = useState("");
console.log(dataFromChild);
return (
<div>
<ChildrenComponent setDataFromChild={setDataFromChild} />
</div>
);
};
export default ParentComponent;
ChildrenComponent
import { useState } from "react";
const ChildrenComponent = ({ setDataFromChild }) => {
const [data, setData] = useState("");
const handleChange = (e) => {
setData(e.target.value);
};
setDataFromChild(data);
return (
<div>
<label htmlFor="data"></label>
<input type="text" id="data" name="data" onChange={handleChange} />
<span>Its Data: </span>
<span>{data}</span>
</div>
);
};
export default ChildrenComponent;
so in above example we can access data
on children component on parent component through function setDataFromChild
using useState
. Whenever the data
onchildren change, the parent dataFromParent
should be change to.