4

I am learning REACT and am having some trouble.

I have multiple pages/components each of these pages has a form in it and I have written a function to handle the form input once submitted.

However i would like to move this function to its own component this way each of the pages simply calls this single component when the form is submitted.

My question is how to do accomplish this using REACT, I have been searching for hours and just cannot figure it out.

Here are two example components:

Form handler/form processing

    'use strict';

import React from 'react/addons';


const FormProcessing = React.createClass({
  _test: function() {
    console.log('test');
   //do something with form values here
  },

  render(){

  }
});
export default FormProcessing;

Example component with form, that needs to call the 'test' function from the 'FormProcessing' component

'use strict';

import React         from 'react/addons';
import {Link}        from 'react-router';
import DocumentTitle from 'react-document-title';

const BreakingNewsPage = React.createClass({

  propTypes: {
    currentUser: React.PropTypes.object.isRequired
  },

  _inputFields: function() {
    return (
      <form id="breakingNewsForm" action="" onclick={call test function from form processing component}>
        <fieldset>
          <legend>Headline</legend>
          <div className="form-group">
            <input type="text" className="form-control input-size-md" id="inputHeadline" placeholder="Headline (Example: Budget Cuts)"/>
          </div>
          <legend>Breaking News</legend>
          <div class="form-group">
            <input type="text" className="form-control input-size-lg" id="inputDescription1" placeholder="Breaking News Description"/>
            <input type="text" className="form-control input-size-lg" id="inputDescription2" placeholder="Breaking News Description"/>
          </div>
        </fieldset>
      </form>
    );
  },

  _formButtons: function() {
    return (
      <div className="form-buttons">
        <button form="breakingNewsForm" type="reset" className="btn-lg">Clear</button>
        <button form="breakingNewsForm" type="submit" classn="btn-lg">Save</button>
      </div>
    );
  },

  render() {
    return (
      <DocumentTitle title="Breaking News">
        <section className="ticker-page page container-fluid">

          <div className="page-title">
            <h1>Breaking News</h1>
          </div>

          <div className="com-md-6">
            {this._inputFields()}
            {this._formButtons()}
          </div>

        </section>
      </DocumentTitle>
    );
  }

});

export default BreakingNewsPage;

Updated code using example provided by: ycavatars

This class renders the form and a few other bits, I have now required the 'FormProcessing class' and have assigned it to _formHandler: FormProcessing,

I then try and call the function handleForm from the formProcessing class using this._formHandler.handleForm(); but i receive this error: Uncaught TypeError: this._formHandler.handleForm is not a function

'use strict';

import React         from 'react/addons';
import {Link}        from 'react-router';
import DocumentTitle from 'react-document-title';
var FormProcessing = require ('../components/FormProcessing.js');

const IntroPage = React.createClass({

  propTypes: {
    currentUser: React.PropTypes.object.isRequired
  },

  _formHandler: FormProcessing,

  // initial state of form
  getInitialState: function() {
    return {
      type: 'info',
      message: ''
    };
  },

  // handles the form callback
  _handleSubmit: function (event) {
    event.preventDefault();
    // Scroll to the top of the page to show the status message.
    this.setState({ type: 'info', message: 'Saving...' }, this._sendFormData);
  },

  // sends form data to server
  _sendFormData: function () {

    this._formHandler._handleForm();

    this.setState({ type: 'success', message: 'Form Successfully Saved' });
    return;
  },

  _inputFields: function() {
    var rows = [];
    for(var i = 1; i <= 12; i++) {
      var placeHolder = 'Intro text line ' + i;
      var inputID = 'inputIntroText ' + i;
      rows.push(<input type="text" className="form-control input-size-lg" name="formInput" id={inputID} placeholder={placeHolder}/>);
    }

    return (
      <form id="introForm" action="" onSubmit={this._handleSubmit}>
        <fieldset>
          <legend>Intro Title</legend>
          <div className="form-group">
            <input type="text" className="form-control input-size-md" name="formInput" id="introTitle" placeholder="Intro Title"/>
          </div>
          <legend>Intro Text</legend>
          <div className="form-group">
            {rows}
          </div>
        </fieldset>
      </form>
    );
  },

  _formButtons: function() {
    return (
      <div className="form-buttons">
        <button form="introForm" type="reset" className="btn-lg">Clear</button>
        <button form="introForm" type="submit" className="btn-lg">Save</button>
      </div>
    );
  },

  render() {

    // checks and displays the forms state
    if (this.state.type && this.state.message) {
      var classString = 'alert alert-' + this.state.type;
      var status = <div id="status" className={classString} ref="status">
                     {this.state.message}
                   </div>;
    }

    return (
      <DocumentTitle title="Intro">
        <section className="intro-page page container-fluid">

          <div className="page-title">
            <h1>Intro</h1>
          </div>

          <div className="com-md-6">
          {status}
            {this._inputFields()}
            {this._formButtons()}
          </div>

        </section>
      </DocumentTitle>
    );
  }

});

export default IntroPage;

This is the FormProcessing class

    'use strict';

import React from 'react/addons';
var IntroPage = require ('../pages/IntroPage.js')

class FormProcessing extends React.Component {

  _handleForm() {
    console.log('you caled me!');
  }

};
export default FormProcessing;
1
  • If you are looking for a reusable function that tests form input, and return OK or NOK values or something, then make a pure JavaScript function and import it. It makes no sense to put this function inside a react component. React components are wrappers for stuff to be rendered in the DOM. If however you want the form to be validated and - based in the outcome - render some other stuff to the DOM, that's a different story. Commented Oct 15, 2015 at 20:26

1 Answer 1

2

You want to invoke FormProcessing._test from BreakingNewsPage component. You have to know the difference between class and instance. React.createClass returns a class which describes your component, and the render method of your component returns a virtual DOM element.

In order to call FormProcessing._test, you have to get the reference to the backing instance of FormProcessing class. That's why react provides a ref. The official tutorial explains the details.

There's an open source project, how to center in css, uses many ref. You could take a look.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the input, I do not quite understand the official tutorial you linked so i looked over the example you provided. However when trying to reference the function in the FormProcessing Class I now get a type error saying it is not a function. I have updated the code in my question to reflect my changes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.