0

Code is given below. where there is a form and I want to get value from textfield of FullName and Email but I am getting error of undefined property for email. I want to access the Text field value. How can I do that i this is not propare way. Note that I am not fluent in React.

Error I am Getting in my COde is Given below.

index.js?aa0c:21 Uncaught TypeError: Cannot read property 'email' of undefined
    at Object.onClick (eval at ./app/containers/LoginPage/index.js (http://localhost:3001/0.chunk.js:7:1), <anonymous>:104:27)
    at Object.proxiedMethod [as onClick] (eval at ./node_modules/react-proxy/modules/createPrototypeProxy.js (http://localhost:3001/main.js:2282:1), <anonymous>:44:30)
    at EnhancedButton._this.handleClick (webpack:///./~/material-ui/internal/EnhancedButton.js?:144:21)
    at Object.ReactErrorUtils.invokeGuardedCallback (webpack:///./~/react-dom/lib/ReactErrorUtils.js?:69:16)
    at executeDispatch (webpack:///./~/react-dom/lib/EventPluginUtils.js?:85:21)
    at Object.executeDispatchesInOrder (webpack:///./~/react-dom/lib/EventPluginUtils.js?:108:5)
    at executeDispatchesAndRelease (webpack:///./~/react-dom/lib/EventPluginHub.js?:43:22)
    at executeDispatchesAndReleaseTopLevel (webpack:///./~/react-dom/lib/EventPluginHub.js?:54:10)
    at Array.forEach (native)
    at forEachAccumulated (webpack:///./~/react-dom/lib/forEachAccumulated.js?:24:9)
    at Object.processEventQueue (webpack:///./~/react-dom/lib/EventPluginHub.js?:257:7)

this is my index.js file.

import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import TextField from 'material-ui/TextField';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import DatePicker from 'material-ui/DatePicker';
import { RadioButton, RadioButtonGroup } from 'material-ui/RadioButton';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import { GridList, GridTile } from 'material-ui/GridList';
import Checkbox from 'material-ui/Checkbox';
import RaisedButton from 'material-ui/RaisedButton';

export default class Login extends Component {
  state = {
    value: null,
  };

  onClick() {
    const text = this.refs.email.getValue();
    console.log("when clicking, the form data is:", text);
    console.log(this.refs.email.getValue());
  }
  handleChange = (event, index, value) => this.setState({ value });
  render() {
    return (
      <div className="md-card">
        <div className="md-card-content large-padding">
          <form id="form_validation" className="uk-form-stacked" >
            <div className="uk-grid" data-uk-grid-margin>
              <div className="uk-width-medium-1-2">
                <div className="parsley-row">
                  <TextField
                    ref={(input) => { this.fullname = input; }}
                    floatingLabelText="Full Name"
                    fullWidth={true}
                  />
                </div>
              </div>

              <div className="uk-width-medium-1-2">
                <div className="parsley-row">
                  <TextField
                    hintText=""
                    ref='email'
                    floatingLabelText="Email"
                    fullWidth={true}
                  />
                </div>
              </div>
            </div>

            <div className="uk-grid" data-uk-grid-margin>
              <div className="uk-width-medium-1-2">
                <div className="parsley-row">
                  <DatePicker
                    hintText="Birthdate"
                    container="inline"
                    mode="landscape"
                    fullWidth={true}
                  />
                </div>
              </div>

              <div className="uk-width-medium-1-2">
                <div className="parsley-row">
                  <label className="uk-form-label">Gender:</label>
                  <RadioButtonGroup name="shipSpeed" defaultSelected="not_light" >

                    <RadioButton
                      value="Male"
                      label="Male"
                    />

                    <RadioButton
                      value="Female"
                      label="Female"
                    />
                  </RadioButtonGroup>
                </div>
              </div>
            </div>
            <div className="uk-grid">
              <div className="uk-width-medium-1-2">
                <div className="parsley-row">

                  <label className="uk-form-label">Hobbies:</label>
                  <span className="icheck-inline">
                    <Checkbox
                      label="Skiing"
                    />
                  </span>
                  <span className="icheck-inline">
                    <Checkbox
                      label="Running"
                    />
                  </span>
                  <span className="icheck-inline">
                    <Checkbox
                      label="Reading"
                    />
                  </span>
                  <span className="icheck-inline">
                    <Checkbox
                      label="Swimming"
                    />
                  </span>
                </div>
              </div>

              <div className="uk-width-medium-1-2">

                <SelectField
                  floatingLabelText="Press?"
                  value={this.state.value}
                  onChange={this.handleChange}
                >
                  <MenuItem value={null} primaryText="" />
                  <MenuItem value={false} primaryText="Internet" />
                  <MenuItem value={true} primaryText="Words of Mouth" />
                </SelectField>
              </div>
            </div>
            <div>
              <TextField
                hintText=""
                floatingLabelText="Message"
                multiLine={true}
                rows={2}
                rowsMax={4}
                fullWidth={true}
              />
            </div>


            <RaisedButton label="Primary" primary={true} onClick={this.onClick} />
          </form >
        </div>
      </div>
    );
  }

}
Developia
  • 3,928
  • 1
  • 28
  • 43
Keyur Patel
  • 95
  • 1
  • 2
  • 16
  • 1
    You have to bind your method or use an arrow function – Andrew Li Jun 16 '17 at 12:58
  • binding issue, use arrow function for that like: `onClick = () => {` as well as don't use string `refs`, as per doc: **We advise against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases. If you're currently using this.refs.textInput to access refs, we recommend the callback pattern instead.** https://facebook.github.io/react/docs/refs-and-the-dom.html#legacy-api-string-refs – Mayank Shukla Jun 16 '17 at 12:58
  • 1
    Possible duplicate of [Unable to access React instance (this) inside event handler](https://stackoverflow.com/questions/29577977/unable-to-access-react-instance-this-inside-event-handler) – Andrew Li Jun 16 '17 at 12:59
  • Possible duplicate of [Cannot read property of undefined when using map to render components](https://stackoverflow.com/questions/42687718/cannot-read-property-of-undefined-when-using-map-to-render-components) – Shubham Khatri Jun 16 '17 at 13:06
  • make use of ref callback instead of string refs. https://stackoverflow.com/questions/38093760/in-react-js-is-there-any-function-similar-like-document-getelementbyid-in-ja/38093981#38093981 – Shubham Khatri Jun 16 '17 at 13:07
  • @AndrewLi, you are right there are multiple questions on the same issue. Also OP was using string refs, so just didnt find it in the same answer. However added that as comment now – Shubham Khatri Jun 16 '17 at 13:09
  • that works for me. thanks – Keyur Patel Jun 16 '17 at 13:24

1 Answers1

1

Getting value of components (ex. Inputs) using ref is not right way in Reactive Functional Programming. (Read this: https://facebook.github.io/react/docs/forms.html)

Try to listen on change event of each Input and keep they changes into state, so you can provide a value to them and control them. This will able you to have values, clean them up or change them from somewhere else.

Here is your code with controlled inputs of fullname and email. Also you can check this out in material-ui docs (under Controlled Example section of each component).

import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import TextField from 'material-ui/TextField';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import DatePicker from 'material-ui/DatePicker';
import { RadioButton, RadioButtonGroup } from 'material-ui/RadioButton';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import { GridList, GridTile } from 'material-ui/GridList';
import Checkbox from 'material-ui/Checkbox';
import RaisedButton from 'material-ui/RaisedButton';

export default class Login extends Component {
  state = {
    value: null,
    fullname: ""
    email: ""
  };

  onClick() {
    console.log(this.state.fullname);
    console.log(this.state.email);
  }
  handleChange = (event, index, value) => this.setState({ value });
  render() {
    return (
      <div className="md-card">
        <div className="md-card-content large-padding">
          <form id="form_validation" className="uk-form-stacked" >
            <div className="uk-grid" data-uk-grid-margin>
              <div className="uk-width-medium-1-2">
                <div className="parsley-row">
                  <TextField
                    ref={(input) => { this.fullname = input; }}
                    floatingLabelText="Full Name"
                    fullWidth={true}
                    value={this.state.fullname}
                    onChange={(event, value) => { this.setState({ fullname: value }); }}
                  />
                </div>
              </div>

              <div className="uk-width-medium-1-2">
                <div className="parsley-row">
                  <TextField
                    hintText=""
                    ref='email'
                    floatingLabelText="Email"
                    fullWidth={true}
                    value={this.state.email}
                    onChange={(event, value) => { this.setState({ email: value }); }}
                  />
                </div>
              </div>
            </div>

            <div className="uk-grid" data-uk-grid-margin>
              <div className="uk-width-medium-1-2">
                <div className="parsley-row">
                  <DatePicker
                    hintText="Birthdate"
                    container="inline"
                    mode="landscape"
                    fullWidth={true}
                  />
                </div>
              </div>

              <div className="uk-width-medium-1-2">
                <div className="parsley-row">
                  <label className="uk-form-label">Gender:</label>
                  <RadioButtonGroup name="shipSpeed" defaultSelected="not_light" >

                    <RadioButton
                      value="Male"
                      label="Male"
                    />

                    <RadioButton
                      value="Female"
                      label="Female"
                    />
                  </RadioButtonGroup>
                </div>
              </div>
            </div>
            <div className="uk-grid">
              <div className="uk-width-medium-1-2">
                <div className="parsley-row">

                  <label className="uk-form-label">Hobbies:</label>
                  <span className="icheck-inline">
                    <Checkbox
                      label="Skiing"
                    />
                  </span>
                  <span className="icheck-inline">
                    <Checkbox
                      label="Running"
                    />
                  </span>
                  <span className="icheck-inline">
                    <Checkbox
                      label="Reading"
                    />
                  </span>
                  <span className="icheck-inline">
                    <Checkbox
                      label="Swimming"
                    />
                  </span>
                </div>
              </div>

              <div className="uk-width-medium-1-2">

                <SelectField
                  floatingLabelText="Press?"
                  value={this.state.value}
                  onChange={this.handleChange}
                >
                  <MenuItem value={null} primaryText="" />
                  <MenuItem value={false} primaryText="Internet" />
                  <MenuItem value={true} primaryText="Words of Mouth" />
                </SelectField>
              </div>
            </div>
            <div>
              <TextField
                hintText=""
                floatingLabelText="Message"
                multiLine={true}
                rows={2}
                rowsMax={4}
                fullWidth={true}
              />
            </div>


            <RaisedButton label="Primary" primary={true} onClick={this.onClick} />
          </form >
        </div>
      </div>
    );
  }

}
Developia
  • 3,928
  • 1
  • 28
  • 43