Mayas
Mayas

Reputation: 1494

Uncaught TypeError: Cannot read property 'toUpperCase' of undefined react state item

I'm new to React and Javascript and I'm trying to render the following React component:

'use strict';
var React = require('react');
import ToReadList from './toreadlist.js';

var ToRead = React.createClass({
getInitialState: function() {
    return { bookTitles: [] };
},
handleSubmit: function(e) {
    e.preventDefault();
    this.state.bookTitles.push(React.findDOMNode(this.refs.bookTitleInput).value.trim());
    this.setState({items: this.state.bookTitles});
},
render: function() {
    return (<div>
        <form onSubmit={this.handleSubmit}><input type="text" ref="bookTitleInput"></input>
            <input type="submit"></input></form>
            <ToReadList bookTitles={this.state.bookTitles} />
    </div>
           );
}
});

module.exports = ToRead;

But I am having the following error on my console: "Uncaught TypeError: Cannot read property 'toUpperCase' of undefined"

I tried to debug (because the error is obscure to me and no line in my code is indicated) and noticed that this particular line:

this.state.bookTitles.push()

causes the error.

Please help!

Edit The error is caused by a webpack var injection function:

function autoGenerateWrapperClass(type) {
      return ReactClass.createClass({
        tagName: type.toUpperCase(),
        render: function() {
          return new ReactElement(
            type,
            null,
            null,
            null,
            null,
            this.props
          );
        }
      });
    }

Upvotes: 9

Views: 65062

Answers (4)

avck
avck

Reputation: 3693

Importing component with incorrect name gave me the same error.

I had imported it as var AreaChart = Charts.AreaChart;

where as in Charts.js it was exported with a small 'c' :

Areachart: Areachart

Changing it to AreaChart: Areachart in Charts.js while exporting solved it.

Upvotes: 2

Mayas
Mayas

Reputation: 1494

My appologies for the poor quality of this post.

I resolved the issue.

Finally, the problem came from the included component:

<ToReadList bookTitles={this.state.bookTitles} />

The error appeared when this.state.bookTitles.push(React.findDOMNode(this.refs.bookTitleInput).value.trim()); was called because bookTitles triggers the error inside the component when it is not empty (i.e <ToReadList bookTitles={["mastery", "foundation"]} /> triggers exactly the same error)

The compenent in question's code is as such:

'use strict';
var React = require('react');
import {ToReadListItem} from './todoreadlistitem.js';

var ToReadList = React.createClass({
    render: function() {
        return (<ul>
            {this.props.bookTitles.map(function(bookTitle){ 
                return (<li>
                    <ToReadListItem bookTitle={bookTitle} isChecked={false}/>
                </li>);
            })}
        </ul>);
    }

});

module.exports = ToReadList;

Changing this line:

import {ToReadListItem} from './todoreadlistitem.js';

To this:

import ToReadListItem from './todoreadlistitem.js';

I know, it is not a great idea to mix es6 syntax with flat one, but I permit myself doing it since the app is for experimentation purposes.

I hope I helped to make things clearer.

Upvotes: 6

Phi Nguyen
Phi Nguyen

Reputation: 3056

I guess the problem is because you try to modify the state directly. Try this:

var newBookTitles = this.state.bookTitles;
var value = React.findDOMNode(this.refs.bookTitleInput).value.trim();
newBookTitles.push(value);
 this.setState({bookTitles: newBookTitles});

I hope it will solve your problem.

Upvotes: 3

Uma Kanth
Uma Kanth

Reputation: 5629

findDOMNode() uses the toUpperCase() function which actually is called on a null.

Example

var x = null
x.toUpperCase()// results in this error.

If you could post the findDOMNode() code, we could trace out the error.

OR

Make sure that the toUpperCase() is called on a non-null object.

Upvotes: 6

Related Questions