I decided to learn React and started with the official tutorial. All is good until I get to this state of my code:
var CommentBox = React.createClass({ render: () => { return ( <div className="commentBox"> <h1> Comments </h1> <CommentList /> <CommentForm /> </div> ); } }); var CommentForm = React.createClass({ render: () => { return ( <div className="commentForm"> Hello, world! I am a comment form; </div> ); } }); var Comment = React.createClass({ rawMarkup: () => { var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); return {__html: rawMarkup}; }, render: () => { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> // <--- [[[[[[ ERROR IS HERE ]]]]]] <span dangerouslySetInnerHtml={this.rawMarkup} /> </div> ); } }); var CommentList = React.createClass({ render: () => { return ( <div className="commentList"> <Comment author="Pete Hunt">This is one comment</Comment> <Comment author="Jordan Walke">This is *another* comment yo</Comment> </div> ); } }); ReactDOM.render( <CommentBox />, document.getElementById('content') );
When I try to run it, I get the following error in devtools:
TypeError: Cannot read property 'props' of undefined
...and the debugger pauses at the marked line (see code). When I mouseover this
in {this.props.author}
, I get a preview of the object which has the props
property and everything...
The "Cannot read properties of undefined" error occurs when trying to access a property on an undefined value. You often get undefined values when: accessing a property that does not exist on an object. accessing an index that is not present in an array.
Components are independent and reusable bits of code. They serve the same purpose as JavaScript functions, but work in isolation and return HTML. Components come in two types, Class components and Function components, in this tutorial we will concentrate on Function components.
“Props” is a special keyword in React, which stands for properties and is being used for passing data from one component to another. But the important part here is that data with props are being passed in a uni-directional flow. ( one way from parent to child)
When creating a list in the UI from an array with JSX, you should add a key prop to each child and to any of its' children. React uses the key prop create a relationship between the component and the DOM element. The library uses this relationship to determine whether or not the component should be re-rendered.
Use function declaration ( render() {}
or render: function {}
) instead of arrow function render: () => {}
var Comment = React.createClass({ rawMarkup() { var rawMarkup = marked(this.props.children.toString(), {sanitize: true}); return {__html: rawMarkup}; }, render() { return ( <div className="comment"> <h2 className="commentAuthor"> {this.props.author} </h2> <span dangerouslySetInnerHtml={this.rawMarkup} /> </div> ); } });
Example
An
arrow function
expression has a shorter syntax compared to function expressions and lexically binds the this value (does not bind its own this, arguments, super, or new.target). Arrow functions are always anonymous.
I had the same error message:
Cannot read property 'props' of undefined
...but from a different cause: when this
is called from within a function, javascript can not reach the variable because this
is in an outer scope. (Note: I was in ES5)
In this case, simply store this
in another variable, prior to the function (in the scope of your component): var that = this;
Then you will be able to call that.props
from within the function.
Hope this helps for other people who had that error message.
Detailed example below:
render: function() { var steps = []; var that = this; // store the reference for later use var count = 0; this.props.steps.forEach(function(step) { steps.push(<Step myFunction={function(){that.props.anotherFunction(count)}}/>); // here you are count += 1; }); return ( <div>{steps}</div> ) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With