user13456401
user13456401

Reputation: 479

React JS how to pass props from a component to another component

I have this react code where I don't know how to do it better.

I will start like this.

I have 3 react components as of now, namely Main, Form, NextButton

So my Main component looks like this:

import React, { Component } from "react";
import Form from "./Form"; 
import NextButton from "./NextButton";

class Main extends Component {
  render() {
    return (
      <div>
        <Form />
        <NextButton />
      </div>
    );
  }
}

export default Main;

Form contains some Text Fields, First Name, Last Name, Age

And NextButton component contains a react-bootstrap Button just to navigate to the next page with react-router-dom, nothing fancy.

My problem is:

I want to pass the value of First Name to the page I render when clicking NextButton through props

So the NextButton would look something like this:

<NextButton firstname={value-i-get-from-Form-component}/>

I know react only allows one-direction data passing, but I want to make this work. Means If my current setup in the Main component is not right, How should I change it?

Upvotes: 0

Views: 2993

Answers (3)

bluetoft
bluetoft

Reputation: 5443

If this were me i would get familiar with using react functional components and hooks since they are way easier to comprehend and understand than redux. They are very powerful and when you write your own hooks you can share logic in a really easy way across components.

React Hooks

function Main() {
  const [title, setTitle] = React.useState(undefined);
  return (
    <div>
      <Form onChange={setTitle} />
      <NextButton title={title} />
    </div>
  );
}

function Form({ onChange }) {
  const [value, setValue] = React.useState("");
  const change = event => {
    setValue(event.target.value);
  };

  return (
    <form
      onSubmit={e => {
        onChange(value);
        e.preventDefault();
      }}
    >
      <input onChange={change} type="text" value={value} />
      <button type="submit">Submit</button>
    </form>
  );
}

function NextButton({ title = "Title" }) {
  return <button>{title}</button>;
}
ReactDOM.render(<Main />, document.getElementById('app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

Upvotes: 0

Barış Aslan
Barış Aslan

Reputation: 21

You can pass data from Form to Main by calling function prop when your First Name input change.

Main component:

import React, { Component } from "react";
import Form from "./Form"; 
import NextButton from "./NextButton";

class Main extends Component {

  constructor(props) { 
    super(props)

    this.handleChange = this.handleChange.bind(this)

    this.state = {
      formValue: {}
    }
  }

  handleChange(formValue) {
    this.setState(formValue)
  }

  render() {
    return (
      <div>
        <Form onChange={this.handleChange} value={this.state.formValue} />
        <NextButton firstName={this.state.formValue.firstName} />
      </div>
    );
  }
}

export default Main;

Form component can be like:

import React, { Component } from "react";

class Form extends Component {

  constructor(props) { 
    super(props)

    this.handleFirstNameChange = this.handleFirstNameChange.bind(this)
    this.handleLastNameChange = this.handleLastNameChange.bind(this)
    this.handleAgeChange = this.handleAgeChange.bind(this)
  }

  handleFirstNameChange(event) {
    if (this.props.onChange) {
      this.props.onChange({
        ...this.props.value,  // keep the other values like lastName, age
        firstName: event.target.value, 
      })
    }
  }

  handleLastNameChange(event) {
    if (this.props.onChange) {
      this.props.onChange({
        ...this.props.value,  // keep the other values like firstName, age
        lastName: event.target.value, 
      })
    }
  }

  handleAgeChange(event) {
    if (this.props.onChange) {
      this.props.onChange({
        ...this.props.value,  // keep the other values like firstName, lastName
        age: event.target.value, 
      })
    }
  }


  render() {
    let { firstName, lastName, age } = this.props.value
    return (
      <form>
        <input type="text" value={firstName} onChange={this.handleFirstNameChange} />
        <input type="text" value={lastName} onChange={this.handleLastNameChange} />
        <input type="text" value={age} onChange={this.handleAgeChange} />
      </form>
    );
  }
}

export default Form;

If your component hierarchy getting complicated you can use Redux.

Upvotes: 0

Grant Singleton
Grant Singleton

Reputation: 1651

With a functional component you can keep state in the parent and pass the hook to the child which can then update the parent. You can also pass a handler to the child and use it to update the parent.

With a functional component it could look like this:

function Main(props) {
   
   const [firstName, setFirstName] = React.useState('');

   return (
     <div>
       <Form setFirstName={setFirstName} firstName={firstName} />
       <NextButton firstName={firstName} />
     </div>
   );
}

Inside Form you can update the state like this

function Form({ firstName, setFirstName }) {

   const handleChange = (event) => {
      setFirstName(event.target.value)
   }
   
   return (
     <div>
       <TextField onChange={handleChange} value={firstName} />
     </div>
   );
}

This will render that new state in the parent which will pass it to NextButton.

Upvotes: 1

Related Questions