Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass form input values to another component React

Currently practicing state and props in React and I have a rather large component which I am trying to split into a few smaller components, however I'm not sure how to pass data from one component to another.

The component currently contains a form with multiple inputs and renders them onSubmit. As far as I understand, the best way to do this is to put the form in it's own component and use props to then pass in the state of the parent component. But how can this be done with multiple inputs and ensure the handleChange and handleSubmit methods work.

Being new to React, i'm still confused as to how to call a method like onChange when it's defined in one component and called in another.

Here's what i've got so far (the one big component...):

export default class App extends Component {
    constructor(props){
      super(props);
      this.state = {
        post: {
          name: "",
          description: "",
          level: "Junior",
          salary: 30000
        },
        jobs: []
      };
    }

  handleChange = e => {
    const { name, value } = e.target;

    this.setState(prevState => ({
      post: { ...prevState.post, [name]: value }
    }));
  };

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

    this.setState(prevState => ({
      jobs: [...prevState.jobs, prevState.post],
      post: { name: "", description: "", level: "", salary: 30000 }
    }));
  };

  render() {
    return (
      <div className="App">
        <nav>
          <button className="btn btn-primary">Post it!</button>
        </nav>


         * This is the section i've been trying to put in a separate component... *


        <div className="form-container">
          <form>
            <div className="form-group">
              <input
                className="col-12 form-control"
                name="name"
                onChange={this.handleChange}
                type="text"
                value={this.state.post.name}
                placeholder="post name"
              />
            </div>
            <div className="form-group">
              <textarea
                className="col-12 form-control"
                name="description"
                onChange={this.handleChange}
                type="text"
                value={this.state.post.description}
                placeholder="post description"
              ></textarea>
            </div>
            <div className="form-group">
              <input
                className="col-12 form-control"
                name="salary"
                onChange={this.handleChange}
                type="number"
                value={this.state.post.salary}
                placeholder="post salary"
              />
            </div>
            <div className="form-group">
              <select
                className="form-control"
                onChange={this.handleChange}
                name="level"
                value={this.state.post.level}>
                  <option>Junior</option>
                  <option>Mid</option>
                  <option>Senior</option>
                  <option>Any</option>
              </select>
             </div>
            <button className="btn btn-primary" onClick={this.handleSubmit}>Submit</button>
          </form>
        </div>



        <div className="post-container">
          <ul>
            {this.state.jobs.map((job, index) => (
              <li key={index}>
                <ul className="post-tile">
                  <li className="post-tile-name">{job.name}</li>
                  <li className="post-tile-level">{job.level}</li>
                  <li className="post-tile-description">{job.description}</li>
                  <li className="post-tile-salary">£{job.salary}</li>
                </ul>
              </li>
            ))}
          </ul>
        </div>
      </div>
    );
  }
}

I've tried moving it and using as:

<Form
   onChange={this.handleChange}
   name={this.state.post.name}
   description={this.state.post.description}
   level={this.state.post.level}
/>

But not sure how to connect it all...any guidance would be really appreciated!

like image 447
Thomas Allen Avatar asked Dec 16 '25 19:12

Thomas Allen


1 Answers

It's right the way you are handling it.

Send post data as 1 propForm component and handle your handleChange and handleSubmit events from the main component.

check this codesandbox example which uses Form.js component.

<Form handleChange={this.handleChange} post={this.state.post} handleSubmit={this.handleSubmit} />

Form.js compnent looks like:

    import React from "react";

    export default ({ handleChange, handleSubmit, post }) => {
      return (
        <div className="form-container">
          <form>
            <div className="form-group">
              <input
                className="col-12 form-control"
                name="name"
                onChange={handleChange}
                type="text"
                value={post.name}
                placeholder="post name"
              />
            </div>
            <div className="form-group">
              <textarea
                className="col-12 form-control"
                name="description"
                onChange={handleChange}
                type="text"
                value={post.description}
                placeholder="post description"
              />
            </div>
            <div className="form-group">
              <input
                className="col-12 form-control"
                name="salary"
                onChange={handleChange}
                type="number"
                value={post.salary}
                placeholder="post salary"
              />
            </div>
            <div className="form-group">
              <select
                className="form-control"
                onChange={handleChange}
                name="level"
                value={post.level}
              >
                <option>Junior</option>
                <option>Mid</option>
                <option>Senior</option>
                <option>Any</option>
              </select>
            </div>
            <button className="btn btn-primary" onClick={handleSubmit}>
              Submit
            </button>
          </form>
        </div>
      );
    };
like image 169
Maxali Avatar answered Dec 19 '25 10:12

Maxali



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!