Binding a function passed to a component

Reading this SO answer , I understand that when I pass the function to the responsive component, I need to bind the function in a constructor like this

constructor(props) { super(props); //binding function this.renderRow = this.renderRow.bind(this); this.callThisFunction = this.callThisFunction.bind(this); } 

or I will get an error.

null is not an object: evaluate this4.functionName

Following this advice, I bound the function in the constructor, but I still get the same error.

I am building a Master / Detail application with React Native based on the Movies example in the native repo response, except that I do not use this syntax

 var SearchScreen = React.createClass({ 

(which is a repo), but rather ES6 style syntax

 class ListOfLists extends Component { 

In my list view, I am making such a line.

  class MovieList extends Component{ constructor(props){ super(props); this.selectMovie = this.selectMovie.bind(this); this.state = { dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }), }; } renderRow( movie: Object, sectionID: number | string, rowID: number | string, highlightRowFunc: (sectionID: ?number | string, rowID: ?number | string) => void, ) { console.log(movie, "in render row", sectionID, rowID); return ( <ListCell onSelect={() => this.selectMovie(movie)} onHighlight={() => highlightRowFunc(sectionID, rowID)} onUnhighlight={() => highlightRowFunc(null, null)} movie={movie} /> ); } selectMovie(movie: Object) { if (Platform.OS === 'ios') { this.props.navigator.push({ title: movie.name, component: TodoListScreen, passProps: {movie}, }); } else { dismissKeyboard(); this.props.navigator.push({ title: movie.title, name: 'movie', movie: movie, }); } } render(){ var content = this.state.dataSource.getRowCount() === 0 ? <NoMovies /> : <ListView ref="listview" renderSeparator={this.renderSeparator} dataSource={this.state.dataSource} renderFooter={this.renderFooter} renderRow={this.renderRow} automaticallyAdjustContentInsets={false} keyboardDismissMode="on-drag" keyboardShouldPersistTaps={true} showsVerticalScrollIndicator={false} renderRow={this.renderRow} } 

The key line is this.selectMovie(movie) . When I click the line with the name of the movie, I get an error

null is not an object: evaluating this4.selectMovie

Question: why does he tell me null is not an object or, rather, why is this function null?

Update:

I added a rendering method to the code to show where renderRow used

+6
source share
2 answers

A way to solve this problem without changing your code is to add this.renderRow = this.renderRow.bind(this) to your class constructor.

 class New extends Component{ constructor(){ this.renderRow = this.renderRow.bind(this) } render(){...} } 

You have added the property renderRow = { this.renderRow } . In fact, renderRow executed with is bound to a null object . Try on the this console in renderRow you will find GlobalObject instead of the Class MovieList that you want.

+9
source

Try using es6 syntax:

 selectMovie = (movie) => { if (Platform.OS === 'ios') { this.props.navigator.push({ title: movie.name, component: TodoListScreen, passProps: {movie}, }); } else { dismissKeyboard(); this.props.navigator.push({ title: movie.title, name: 'movie', movie: movie, }); } } 

and then

 constructor(props) { super(props); this.selectMovie = this.selectMovie(); this.state = { dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }) }; } 

and

 renderRow = (...) => { return ( <ListCell onSelect={this.selectMovie(movie)} onHighlight={() => highlightRowFunc(sectionID, rowID)} onUnhighlight={() => highlightRowFunc(null, null)} movie={movie} /> ); } 
+1
source

All Articles