8
votes

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
          );
        }
      });
    }
4
In your code is no .toUpperCase.pavel
Do you mean that it is called nowhere?Mayas
this.state.bookTitles.push(React.findDOMNode(this.refs.bookTitleInput)); If the above line is in error try to push with a constant string. I think findDOMNode is returning null and push is doing some kind of uppercase on it which is resulting in error.Biswanath
@Biswanath yes i tried this: this.state.bookTitles.push("this is a title"); same thing. I added this: console.log(React.findDOMNode(this.refs.bookTitleInput)) and the input is correctly printed. It is worth to notice that this code (this.state.bookTitles.push("this is a title");) works perfectly under React 0.12 but the problem appears when I upgrade to 0.13Mayas
@panther the error appears in the "function autoGenerateWrapperClass(type) { return ReactClass.createClass({ tagName: type.toUpperCase(), " code of WEBPACK VAR INJECTIONMayas

4 Answers

5
votes

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.

5
votes

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.

2
votes

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.

1
votes

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.