Home > Enterprise >  Transfer Data from child component to parent component on React
Transfer Data from child component to parent component on React

Time:09-28

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.

  • Related