Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncaught TypeError: Cannot read property 'state or props' of undefined

So I started converting my application from ES2015 to ES6 which uses React.

I have a parent class and a child class like so,

export default class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            code: ''
        };
    }

    setCodeChange(newCode) {
        this.setState({code: newCode});
    }


    login() {
        if (this.state.code == "") {
            // Some functionality
        }
    }

    render() {
        return (
            <div>
                <Child onCodeChange={this.setCodeChange} onLogin={this.login} />
            </div>
        );
    }
}

Child class,

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

    handleCodeChange(e) {
        this.props.onCodeChange(e.target.value);
    }

    login() {
        this.props.onLogin();
    }

    render() {
        return (
            <div>
                <input name="code" onChange={this.handleCodeChange.bind(this)}/>
            </div>
            <button id="login" onClick={this.login.bind(this)}>
        );
    }
}

Child.propTypes = {
    onCodeChange: React.PropTypes.func,
    onLogin: React.PropTypes.func
};

However this causes the following error,

this.state is undefined

It refers to,

if (this.state.code == "") {
    // Some functionality
}

Any idea what could be causing this ?

like image 683
nixgadget Avatar asked Sep 15 '16 05:09

nixgadget


People also ask

How do you fix undefined properties Cannot be read?

To solve the "Cannot read properties of undefined" error, make sure that the DOM element you are accessing exists. The error is often thrown when trying to access a property at a non-existent index after using the getElementsByClassName() method. Copied!

How do you pass props in react JS?

To pass props, add them to the JSX, just like you would with HTML attributes. To read props, use the function Avatar({ person, size }) destructuring syntax. You can specify a default value like size = 100 , which is used for missing and undefined props.

How do you create a component of a react function?

We can create a functional component to React by writing a JavaScript function. These functions may or may not receive data as parameters. In the functional Components, the return value is the JSX code to render to the DOM tree. Example: Program to demonstrate the creation of functional components.


1 Answers

You can use arrow function to bind you functions. You need to bind you functions both in child as well as parent components.

Parent:

export default class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            code: ''
        };
    }

    setCodeChange = (newCode) => {
        this.setState({code: newCode});
    }


    login = () => {
        if (this.state.code == "") {
            // Some functionality
        }
    }

    render() {
        return (
            <div>
                <Child onCodeChange={this.setCodeChange} onLogin={this.login} />
            </div>
        );
    }
}

Child

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

    handleCodeChange = (e) => {
        this.props.onCodeChange(e.target.value);
    }

    login = () => {
        this.props.onLogin();
    }

    render() {
        return (
            <div>
                <input name="code" onChange={this.handleCodeChange}/>
            </div>
            <button id="login" onClick={this.login}>
        );
    }
}

Child.propTypes = {
    onCodeChange: React.PropTypes.func,
    onLogin: React.PropTypes.func
};

There are other ways to bind the functions as well such as the one you are using but you need to do that for parent component too as <Child onCodeChange={this.setCodeChange.bind(this)} onLogin={this.login.bind(this)} />

or you can specify binding in the constructor as

Parent:

constructor(props) {
    super(props);
    this.state = {
        code: ''
    };
 this.setCodeChange = this.setCodeChange.bind(this);
 this.login = this.login.bind(this);
}

Child

constructor(props) {
    super(props);
    this.handleCodeChange = this.handleCodeChange.bind(this);
    this.login = this.login.bind(this);
}
like image 136
Shubham Khatri Avatar answered Oct 18 '22 19:10

Shubham Khatri