Search code examples
reactjsmdbreact

How to get the value from one component(Child Component) to another component (Parent Component) in reactjs?


I'am working Reactjs Weather project. I'am getting the value in one of the method in Child Component (Form.js) after submitting and I need to get that value in Parent Component (App.js). How to get that value?

  1. App.js file (Parent Component)
getWeather = async (e) => {
    e.preventDefault();

}
  1. Form.js file (Child Component)
import React, { Component } from 'react'
import Background from '../video/rain_drop2.jpg';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

import { MDBContainer,
    MDBRow,
    MDBCol,
    MDBCard,
    MDBCardBody,
    MDBCardHeader,
    MDBBtn,
    MDBInput } from 'mdbreact'


const sectionStyle = {
    backgroundImage: `url(${Background})`,
    opacity: '0.92',
    width: '90%',
    backgroundSize: 'cover',
    backgroundPosition: 'center',
    height:'99%',
    position:'absolute',
    filter:'blur(1.8px)'
    };

class Form extends React.Component {
  constructor(props){
    super(props);

    this.state = {
      fields: {},
      errors: {}
    }
  }

  handleValidation(){
    let fields = this.state.fields;
    let errors = {};
    let formIsValid = true;

    //Name
    if(!fields["city"]){
      formIsValid = false;
      errors["city"] = "Cannot be empty";
    }

    this.setState({errors: errors});
    return formIsValid;
  }

  submitDetails = (e) => {
    e.preventDefault();

    // I want this value to be accessed in App.js file
    const city = e.target.city.value
    console.log('VALUE', city)

    browserHistory.push()
    if(this.handleValidation()){
      toast("Form Submitted!.")
    }else{
      toast("Form has errors.")
    }

  }

  handleChange(field, e){           
    let fields = this.state.fields;
    fields[field] = e.target.value;        
    this.setState({fields});
  }

  render(){
    return (

      <div>  
<MDBContainer>
<MDBRow>
  <MDBCol>
  <MDBCard  style={sectionStyle}></MDBCard>
  <MDBCard className="card" style={{zIndex:'1', background: 'none'}}>
  <MDBCardBody >
    <MDBCardHeader style={{background: '#ecf0f1', opacity:'0.7', borderRadius: '10px',
    fontFamily: 'Josefin Sans'}}>
      <h3 className="my-3 text-center" style={{color: '#535c68'}}>
         Weather Finder
      </h3>
    </MDBCardHeader>
    <br/>
    <form onSubmit= {this.submitDetails.bind(this)}>
      <div className="blue-grey-text">
      <span className="error">{this.state.errors["name"]}</span>
        <MDBInput
          ref="city"
          label="City"
          icon="city"
          type="text"
          name="city"
          id="text-input"
          onChange={this.handleChange.bind(this, "city")}
          value={this.state.fields["city"]}
        />
        <span style={{color: "red"}}>{this.state.errors["city"]}</span>

        </div>
        <br/>

      <div className="text-center mt-4">
        <MDBBtn
          color="blue-grey"
          className="mb-3"
          type="submit"
          value="Submit"
        >
          Search Weather
        </MDBBtn>
        <ToastContainer />
      </div>
      </form>
    </MDBCardBody>
    </MDBCard>
    </MDBCol>
  </MDBRow>
  </MDBContainer>
  </div>
    )
  }
}

export default Form;

Any suggestions highly appreciated... Thanks in advance


Solution

  • When rendering the child component in parent component, pass a function, defined in parent component, to the child component as a prop.

    When you get the required value in child component, call the function that was passed from parent component as a prop and pass the value to that function as an argument.

    Parent Component

    // function to be called from child component
    foo = (value) => {
       // code
    };
    
    render() {
       return (
          <ChildComponent foo={this.foo}/>
       );
    }
    

    Child Component

    bar = () => {
       const value = // get the value
       // call the foo function of parent component and pass the value
       this.props.foo(value);
    };