2017-06-10 4 views
7

Ich implementiere eine Wortsuchfunktion in meiner React Native App. Ich habe einen MobX Store, wordStore. Jede Textänderung löst über die Aktion setFilter eine Datenbankabfrage aus. Das alles funktioniert unter der Haube, wie ich von der Konsolen-Debug-Ausgabe sehen kann. Die Komponente WordList scheint zu verschwinden, sobald irgendwelche Aktualisierungen ausgelöst werden, d. H. Wenn ich eine Standardfilterzeichenfolge festlege, werden übereinstimmende Elemente in der Liste angezeigt, aber sobald sich ein Text ändert, verschwindet er.Komponente verschwindet bei Aktualisierung

Gibt es etwas, was ich vermisse? Das Seltsame ist, dass die Methode WordList.render() ausgeführt wird, obwohl sie nicht sichtbar ist.

EDIT: Rendern des .toString() Methode des Array arbeitet von der enthaltenden Komponente in Ordnung, aber seltsam Iterieren über das Array auch das gleiche Verhalten zeigt, auf Update verschwinden.

Die enthaltenden Komponente:

const WordSearch = observer(class WordSearch extends React.Component { 

    constructor(props) { 
     super(props); 
    } 


    render() { 
     let words = wordStore.getWords(); // For debugging 
     return (
     <View> 
      <TextInput 
      style={styles.textInput} 
      onChangeText={(filter) => wordStore.setFilter (filter)} 
      value={wordStore.filter} 
      /> 
      <Text>{words.toString()}</Text> <!-- This works --> 
      <View style={{flex:1}} key={wordStore.filter}> <!-- This disappears too --> 
      {words.map((word, i) => { 
      console.log ('word: '+word); 
      return <View style={{flex:1}} key={i}> 
       <Text>{word}</Text> 
      </View> 
      })} 
      </View> 
      <WordList {...this.props} /> 
     </View> 
    ); 

    } 
    // ... 
}); 

und der Wortbestandteil:

const WordList = observer(class WordList extends Component { 

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

    componentWillReact() { 
    console.log("I will re-render, since the words have changed!"); 
    } 

    componentWillUpdate() { 
    console.log("Will update") 

    let words = wordStore.getWords(); 
    this.dataSource = this.dataSource.cloneWithRows(words); 
    console.log ("words:"); 
    console.log (words); 
    } 

    render() { 
    return (
     <View style={styles.container}> 
     <ListView 
      key={wordStore.words} 
      dataSource={this.dataSource} 
      renderRow={this.renderWordRow} 
      style={styles.listView} 
     /> 
     </View> 
    ) 
    } 

    renderWordRow = (word, sectionID, rowID) => { 
    console.log ('rendering word row: '+word) 
    return (
     <TouchableHighlight 
      underlayColor="grey"> 
      <View style={styles.rowContainer}> 
      <Text style={styles.title}>{word}</Text> 
      </View> 
     </TouchableHighlight> 
    );  
    } 
}); 

export default WordList; 
+0

Wie sieht das Konsolenfenster aus, nachdem die App gestartet wurde, und dann den Filter wechseln? Haben Sie verifiziert, dass 'getWords()' funktioniert so wie es sollte? – Glubus

+0

@Glubus ja alles funktioniert wie es sollte, Konsolenausgabe zeigt die aktualisierten Ergebnisse, und auch die Ausgabe von 'words.toString()' in der enthaltenen Komponente wird wie erwartet aktualisiert – Adamski

Antwort

9

Das war ein dummer Fehler. Es wurde aufgrund der flex nicht in der enthaltenden Ansicht festgelegt. Der richtige Code für das obige Beispiel:

<View style={{flex:1}}> 
     <TextInput 
     style={styles.textInput} 
     onChangeText={(filter) => wordStore.setFilter (filter)} 
     value={wordStore.filter} 
     /> 
     <WordList {...this.props} /> 
    </View> 
+0

Danke. Ich hatte ein ähnliches Problem, bei dem eine Komponente nicht gerendert wurde, weil einer der Eltern in der Hierarchie kein 'flex: 1' hatte. –

Verwandte Themen