How to send the form data up a state using react-hook-form in react?

Viewed 5981

I am new to React. What I want to do is have a submit button to log the data/state onto the console from the form's input fields which is in another component. To implement this, I have the ResultList component which renders the Filter component which has the form. When the submit button is clicked the data from the input fields should log onto the console. I used react-form-hook to implement the form. This is the link to the sandbox

ResultList component looks like:

import React, { Component } from 'react';
import { render } from 'react-dom';
import Filter from './Filter';

import { Button, Dropdown, Input, } from 'semantic-ui-react';

export default class ResultList extends Component {
   constructor(props){
      super(props);

      this.state = {
          myName: '',
          myEmail: ''
      };
    }

    handleParentData = (formModel) => {
      console.log(formModel);

      this.setState({...formModel},()=>alert(JSON.stringify(this.state)));
    }

  render() {
    return (
        <div>

          <Filter handleData={this.handleParentData}/>
          <p>{this.state.myName}</p>  
          <p>{this.state.email}</p>     
        </div>
    )
  }
}

and Filter component looks like:

import React, { Component } from 'react';
import {useForm} from 'react-hook-form';

export default function Filter() {

  const {register,handleSubmit} = useForm();

  const onSubmit = (data) => {
    // console.log(data);
    this.props.handleData(data);
  } 

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        Name: <input type="text" name="myName" ref={register}/>
        <br />
        Email: <input type="text" name="myEmail" ref={register}/>
        <br /><br />
        <input type="submit" value="Submit"/>
      </form>
    </div>
  )

}
2 Answers

Need to accept props in the functional component, and change the onSubmit handler to use props and not this.props. Functional components are instanceless and have no this object.

export default function Filter(props) {

  const { register, handleSubmit } = useForm();

  const onSubmit = data => {
    props.handleData(data);
  } ;

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        Name: <input type="text" name="myName" ref={register}/>
        <br />
        Email: <input type="text" name="myEmail" ref={register}/>
        <br /><br />
        <input type="submit" value="Submit"/>
      </form>
    </div>
  );
}

Alternatively you can destructure props right in the function signature

export default function Filter({ handleData }) {

  const { register, handleSubmit } = useForm();

  const onSubmit = data => handleData(data);

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        Name: <input type="text" name="myName" ref={register}/>
        <br />
        Email: <input type="text" name="myEmail" ref={register}/>
        <br /><br />
        <input type="submit" value="Submit"/>
      </form>
    </div>
  );
}

You need to pass props to Filter:

export default function Filter(props) {

and remove .this.props:

props.handleData(data);

Full code:

import React, { Component } from 'react';
import {useForm} from 'react-hook-form';

export default function Filter(props) {

  const {register,handleSubmit} = useForm();

  const onSubmit = (data) => {
    // console.log(data);
    props.handleData(data);
  } 

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        Name: <input type="text" name="myName" ref={register}/>
        <br />
        Email: <input type="text" name="myEmail" ref={register}/>
        <br /><br />
        <input type="submit" value="Submit"/>
      </form>
    </div>
  )

}

You also need to change from {this.state.email} to {this.state.myEmail}

Full code:

import React, { Component } from 'react';
import { render } from 'react-dom';
import Filter from './Filter';

import { Button, Dropdown, Input, } from 'semantic-ui-react';

export default class ResultList extends Component {
   constructor(props){
      super(props);

      this.state = {
          myName: '',
          myEmail: ''
      };
    }

    handleParentData = (formModel) => {
      console.log(formModel);

      this.setState({...formModel},()=>alert(JSON.stringify(this.state)));
    }


  render() {
    return (
        <div>

          <Filter handleData={this.handleParentData}/>
          <p>{this.state.myName}</p>  
          <p>{this.state.myEmail}</p>     

        </div>
    )
  }
}
Related