Pass form input values to another component React

19,353

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>
      );
    };
Share:
19,353

Related videos on Youtube

Thomas Allen
Author by

Thomas Allen

Software Engineer

Updated on June 04, 2022

Comments

  • Thomas Allen
    Thomas Allen almost 2 years

    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!

    • Tholle
      Tholle over 5 years
      If you want to create a separate Form component it might be a good idea to put all the form specific state in the Form component, and just pass down a function as prop e.g. onSubmit that you want to run when the form is submitted.
    • Maxali
      Maxali over 5 years
      You can check this codesandbox example which uses Form.js component.
  • some_groceries
    some_groceries about 5 years
    instead of onClick={handleSubmit} handler on the submit button we should use onSubmit-{handleSubmit} on the form tag, so that enter would also work as form submit