Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncaught TypeError: Cannot read property 'value' of undefined in REACT JS

I am creating a login form using REACT JS as front-end and PHP as back-end. I am trying to get input values. Code is as below:

import React, { Component} from 'react';
import ReactDOM from 'react-dom';
import {Button, IconButton} from 'react-toolbox/lib/button';
import Input from 'react-toolbox/lib/input';

export default class Login extends React.Component {

constructor() {
    super();
    this.state = {email: ''};
    this.state = {password: ''};
    this.onSubmit = this.onSubmit.bind(this);
    this.handleEmailChange = this.handleEmailChange.bind(this);
    this.handlePasswordChange = this.handlePasswordChange.bind(this);
}
handleEmailChange(e) {
    this.setState({email: e.target.value});
}
handlePasswordChange(e) {
    this.setState({password: e.target.value});
}
onSubmit() {
    fetch('http://xyz/check-login', {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email: this.state.email,
        password: this.state.password,
      })
    })
}

And form is as below:

<form name="Login">
<Input type="text" name="email" value={this.state.email} placeholder="Email Id" className="form-control" onChange={this.handleEmailChange} />
<Input name="password" value={this.state.password} placeholder="Password" type="password" className="form-control m-b-10" onChange={this.handlePasswordChange} />   
<Button type="button" className="m-t-20 orange" label="Sign in " onClick={this.onSubmit} /> 
</form>

But getting the following error:

Uncaught TypeError: Cannot read property 'value' of undefined

I am using react-toolbox. So, I am using component from https://github.com/react-toolbox/react-toolbox/blob/dev/components/input/Input.js and component from https://github.com/react-toolbox/react-toolbox/blob/dev/components/button/Button.js.

like image 723
Triyugi Narayan Mani Avatar asked Dec 09 '16 06:12

Triyugi Narayan Mani


People also ask

How do you fix Cannot read property of undefined in react?

The "Cannot read property 'props' of undefined" error occurs when a class method is called without having the correct context bound to the this keyword. To solve the error, define the class method as an arrow function or use the bind method in the class's constructor method.

What does Cannot read property of undefined mean?

Undefined means that a variable has been declared but has not been assigned a value. In JavaScript, properties and functions can only belong to objects. Since undefined is not an object type, calling a function or a property on such a variable causes the TypeError: Cannot read property of undefined .


2 Answers

First of all, what are <Input ..../> and <Button .../>? Are they your components or they are only form input fields?

I suppose that they are only form fields, thus they need to be in lower case <input ..../> , <button .../>.

Try to bind your functions inside render, like : this.functionName.bind(this).

This is a working code :

class Test extends React.Component {
    constructor(props){
        super(props);

      this.state = {
          email: '',
          password: '',
      };
    }

    handleEmailChange(e) {
        this.setState({email: e.target.value});
    }
    handlePasswordChange(e) {
        this.setState({password: e.target.value});
    }


    render(){
        return (
        <div>
            <form name="Login">
              <input type="text" name="email" value={this.state.email} placeholder="Email Id" className="form-control" onChange={this.handleEmailChange.bind(this)} />
              <input name="password" value={this.state.password} placeholder="Password" type="password" className="form-control m-b-10" onChange={this.handlePasswordChange.bind(this)} />   
              <button type="button" className="m-t-20 orange" label="Sign in " onClick={this.onSubmit}>Sign in</button> 
          </form>
        </div>
      )
    }
}

React.render(<Test />, document.getElementById('container'));

Here is the fiddle.

UPDATE

I tested it here :

 constructor(props){
    super(props);

    this.state = {
            name: '',
        email: ''
    }
  }

  handleChange(name, value){
    let state = this.state;
    state[name] = value;
    this.setState({state});

  }

  render () {
    return (
      <section>
        <Input type='text' label='Name' name='name' value={this.state.name} onChange={this.handleChange.bind(this, 'name')} maxLength={16} />
        <Input type='email' label='Email address' icon='email' value={this.state.email} onChange={this.handleChange.bind(this, 'email')} />
      </section>
    );
  }

I'm not sure how it works, but it pass name and value as params to the handleChange function, thus, you can get value as a second param. You don't need event.

like image 155
Boky Avatar answered Sep 22 '22 21:09

Boky


First change your this.state in constructor to single - this.state = {emai:'',password:''}, then try to bind handleEmailChange and handlePasswordChange inside of input instead in constructor, u need to set this direct to input,

UPDATE

or if Input and Button are components, u need implement changeMethod and onChange event in them, and send value back to component Login via callback

HOW IT WORKS -

 class Input extends React.Component{
            constructor(props){
                super(props);
                this.state= {
                    value : this.props.value
                }
            }
            componentWillReceiveProps(nextProps){
                 this.setState({
                      value: nextProps.value,
                  })
            }

            render(){
                return(
                    <input onChange={this.handleChangeValue.bind(this)} type="text" name={this.props.name} value={this.state.value} placeholder={this.props.placeholder} className={**just class name or send via props too**}  />
                )
            }
            handleChangeValue(e){
                this.setState({value:e.target.value});
                this.props.changeValue(e.target.value); 
            }
  }
        
        class Login extends React.Component{
            constructor(props){
                super(props);
                this.state= {
                    emailValue : '',
                    passwordValue: '',
                    ...
                }
            }
            render(){
                return(
                      <div>
                        <Input type="text" name='email' value={this.state.emailValue} placeholder={'Write email'} className='someName' changeValue={this.changeEmailValue.bind(this)} />
                        <Input type="text" name='password' value={this.state.passwordValue} placeholder={'Write password'} className='someName' changeValue={this.changePasswordValue.bind(this)} /> 
                     
                      </div>

                    )
               }
            changeEmailValue(value){
                this.setState({emailValue:value});
            }
        
            changePasswordValue(value){
                this.setState({passwordValue:value});
            }
        }
like image 42
Lukáš Unzeitig Avatar answered Sep 22 '22 21:09

Lukáš Unzeitig