2016-03-10 14 views
7

Lavorare con un controllo ListView in React-nativa, ho visto che non è la stessa, spostando oggetti di scena per la voce di elenco,React-Native ListView renderRow problemi passando oggetti di scena. Il modo giusto o nel modo sbagliato

  1. funzioni passare come oggetti di scena solo con il riferimento, e richiamare i parametri nel componente bambino, o

  2. funzioni Passo come oggetti di scena con parametri definiti, e richiamare la funzione senza parametri nel bambino

nessuna delle soluzioni funziona.

La funzione invocata sono creatori di azioni di Redux e inviati. E 'questo un problema di Redux o React-Native (forse ReactJS)

Si tratta di un frammento di codice, mercato come // ERRORE le righe di codice che does'nt lavoro seguita da quelli buoni

class App extends Component { 

    // On props 
    // data: an Array 
    // doThis: an action creator of Redux 
    // doThat: idem 

    constructor(){ 
    super(); 
    this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    } 

    render() { 
    const dataSource = this.ds.cloneWithRows(this.props.data); 

    return (
     <View> 
     <ListView style={{flex:1}} 
      dataSource={dataSource} 
      renderRow={(rowData, sectionID, rowID) => 
       <Item rowData={rowData} 
       //ERROR 
       //onPress={this.props.doThis} 
       //onLongPress={this..props.doThat} 
       //RIGHT NO ERROR TOO 
       onPress={() => this.props.doThis(rowData)} 
       onLongPress={() => this.props.doThat(rowData)} 
       /> 
      } 
      /> 
     </View> 
    ) 
    } 
} 

class Item extends Component { 
    render() { 
    return (
     <View> 
     <TouchableHighlight 
      //ERROR 
      //onPress={() => { this.props.onPress(this.props.rowData) }} 
      //onLongPress={() => { this.props.onLongPress(this.props.rowData) }} 
      //WRONG TOO 
      onPress={this.props.onPress} 
      onLongPress={this.props.onLongPress} 
      > 
      <Text> 
      {rowData} 
      </Text> 
     </TouchableHighlight> 
     </View> 
    ); 
    } 
} 

c'è un repo con questo problema qui https://github.com/srlopez/test Grazie in anticipo

risposta

0

Probabilmente è un problema con il tuo this che non viene impostato direttamente nella tua chiusura.

Prova vincolante in questo modo:

class Item extends Component { 
    render() { 
    return (
     <View> 
     <TouchableHighlight 
      onPress={this.props.onPress.bind(this, this.props.rowData)} 
      onLongPress={this.props.onLongPress.bind(this, this.props.rowData)} 
      > 
      <Text> 
      {rowData} 
      </Text> 
     </TouchableHighlight> 
     </View> 
    ); 
    } 
} 
+0

Hi @Moti Azu, Davvero non so cosa c'è di sbagliato nella mia risposta e nella tua. Entrambi sbagliati. Stavo pensando al modo giusto per passare il callbak su renderRow e su Item basta richiamare la funzione. Ma non funziona. questo è il repo di testare, i Can you help me: [https://github.com/srlopez/test](https://github.com/srlopez/test) – Santi

+0

Hi @Moti Azu per evitare discussioni estese qui (non mi piacciono i revisori) ho rimosso i miei commenti. La lunga spiegazione è sul repository. Facendo clic sui pulsanti sul componente principale funziona bene (aggiungi, rimuovi, aggiorna, ecc. Nell'elenco) ma fai clic sugli elementi in Elenco, non esegue lo stesso comportamento, quindi rimuovi tutti gli elementi da quello cliccato fino alla fine. Il comportamento desiderato è quello di cambiare lo stato di un oggetto, ma lo stato cambia e rimuove gli elementi rimanenti. Mi dispiace Moti per il mio pessimo inglese. – Santi

4

Se i callback di alto livello accettano un parametro, è necessario assicurarsi che le funzioni anonime accettano un parametro così (Nota: la creazione di funzioni anonime utilizzando la sintassi freccia lega automaticamente la nostra funzione al valore di this nel contesto corrente). Credo che avete assistito una combinazione di problemi in cui o il tuo callback erano legati al contesto non corretta (la finestra) o non accettavano gli argomenti passati:

class App extends Component { 

    // On props 
    // data: an Array 
    // doThis: an action creator of Redux 
    // doThat: idem 

    constructor(){ 
    super(); 
    this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    } 

    render() { 
    const dataSource = this.ds.cloneWithRows(this.props.data); 

    return (
     <View> 
     <ListView style={{flex:1}} 
      dataSource={dataSource} 
      renderRow={(rowData, sectionID, rowID) => 
       <Item rowData={rowData} 
        onPress={(data) => this.props.doThis(data)} 
        onLongPress={(data) => this.props.doThat(data)} /> 
      }/> 
     </View> 
    ) 
    } 
} 

class Item extends Component { 
    render() { 
    return (
     <View> 
     <TouchableHighlight 
      onPress={() => this.props.onPress(this.rowData)} 
      onLongPress={() => this.props.onLongPress(this.rowData)}> 
      <Text> 
      {rowData} 
      </Text> 
     </TouchableHighlight> 
     </View> 
    ); 
    } 
} 
+0

Grazie @ calvin-belden, Provo il tuo approcio su questo [repo] (https://github.com/srlopez/test), ma il comportamento del risultato è lo stesso. Ho codificato 'onPress = {(rowID) => {this.props.update (rowID)}} 'su renderRow in ListView e' onPress = {() => this.props.onPress (rowID)} 'su Articolo, e Modifica articolo, ma gli articoli rimasti vengono cancellati. – Santi

+0

La riga ID è definita nella funzione 'render' del componente Item? Puoi impostare un punto di interruzione (o in qualche modo il debug) per vedere se il gestore genitore viene chiamato? –

+1

Ciao di nuovo @ calvin-belden @ moti-azu. Fatto! Il modo giusto è come questo 'onPress = {() => this.props.update (parseInt (rowID))}' su renderRow e 'onPress = {this.props.onPress}' su Articolo.Ma la cosa importante è il 'parseInt' di' rowID' nel repository. Il rowID è una stringa e non un numero !. Quindi la funzione nel riduttore (Redux) si converte sempre in 0, e poi tutto sbagliato! Grazie mille entrambi! – Santi

Problemi correlati