I have the following code, which results in this.state
being undefined
:
articles.js
const React = require('react-native')
const _ = require('lodash')
const styles = require('../styles/articles')
const api = require('../data/api')
const {
ListView,
View,
Text,
Image
} = React
const Articles = React.createClass({
getInitialState: () => {
return { articles: [] }
},
componentDidMount: () => {
const self = this
const body = [{ screen_name: 'wired' }]
api.get('timelines', body)
.then(data => {
self.setState({ articles : data })
})
},
renderArticle: article => {
const { container, thumbnail, rightContainer, title, year } = styles;
return (
<View key={article.id} style={container}>
<Text style={title}>{article.title}</Text>
</View>
)
},
render: () => {
console.log('render', this.state)
const articles = _.map(this.state.articles, article => renderArticle(article), this)
return <View style={styles.listView}>{articles}</View>
}
})
module.exports = Articles
index.ios.js
const React = require('react-native')
const Articles = require('./src/components/articles')
React.AppRegistry.registerComponent('movies', () => Articles)
console.log
in the render
method says this.state
is undefined. What am I doing wrong?
To check for undefined in React, use a comparison to check if the value is equal or is not equal to undefined , e.g. if (myValue === undefined) {} or if (myValue !== undefined) {} . If the condition is met, the if block will run.
This is because when you use an arrow function, the event handler is automatically bound to the component instance so you don't need to bind it in the constructor. When you use an arrow function you are binding this lexically.
The "cannot read property 'setState' 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 classes' constructor method.
You're using React.createClass
with arrow functions, this messes up the binding to this
.
So instead of doing
render () => {}
do
render: function () {}
or switch to ES6 classes, which would make your current class look like this
class Articles extends React.Component {
renderArticles = () => {}
render() {} // render and other lifecycle methods are always left without an arrow function
}
In ES6, React no longer supports the auto binding feature that .createClass
provided for you which is why you want to use either and arrow function or use .bind
when writing ES6 React components.
Also note that when using Babel, ES6 and React some features might be hidden behind stage flags, you'd have to investigate those as you go along!
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