2016-02-17 17 views
5

lettura this SO answer, capisco che quando passo di una funzione a un componente reagire, devo legare una funzione nel costruttore come questovincolante una funzione passata a un componente

constructor(props) { 
    super(props); 

    //binding function 
    this.renderRow = this.renderRow.bind(this); 
    this.callThisFunction = this.callThisFunction.bind(this); 
    } 

o ti ottenere un errore come questo

null non è un oggetto: la valutazione this4.functionName

Seguendo questo consiglio, ho legato la funzione nel costruttore, ma sto ancora ricevendo lo stesso errore.

Sto facendo un'applicazione master/dettaglio con Reagire nativo basato sull'esempio Movies nel repository nativo reagire, se non che io non uso questa sintassi

var SearchScreen = React.createClass({ 

(che è ciò che il repo è), ma piuttosto questo ES6 sintassi stile

class ListOfLists extends Component { 

a mio avviso lista, io rendo fila come questo.

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} 
    } 

La linea fondamentale è this.selectMovie(movie). Quando scatto una riga con un nome di film, ottengo un errore

null non è un oggetto: evaluating this4.selectMovie

Domanda: perché è dicendo mi null is not an object o meglio il motivo per cui è che la funzione nulla?

Aggiornamento:

ho aggiunto il metodo di rendering per il codice per mostrare dove renderRow si sta abituando

+0

Non riesco a vedere dove si usa 'renderRow', ma potrebbe essere necessario associarlo anche a questo. Tuttavia non è necessario combinare le funzioni freccia e il binding. – sodik

+0

@sodik Ho aggiornato l'OP per mostrare dove viene usato 'renderRow' – Leahcim

risposta

9

Il modo per risolvere questo problema senza modificare molto il codice è aggiungere this.renderRow = this.renderRow.bind(this) al costruttore della classe.

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

    render(){...} 
} 

voi hanno aggiungere la proprietà renderRow = { this.renderRow }, infatti il ​​renderRow eseguito con binded to null object .Try consolare this in renderRow troverete che è GlobalObject invece di Class MovieList che si desidera.

+1

Potrei essere confuso, ma questa è davvero la soluzione corretta a questo problema?La risposta non spiega quale sia la causa del problema in primo luogo e sembra un trucco. – Felipe

+0

@PixelCakeGames Grazie per aver capito che la risposta non è stata data all'inizio, mentre io non questo è un 'hack' invece di una soluzione. È chiaro che il metodo renderRow deve essere eseguito con larghezza di associazione ad un oggetto 'null' e questo è ciò che @Leahcim si è schiantato. –

1

Prova utilizzando la sintassi ES6:

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, 
    }); 
    } 
} 

e poi

constructor(props) { 
    super(props); 

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

e

Problemi correlati