2017-06-10 2 views
7

Je suis en train d'implémenter une fonction de recherche de mots dans mon application React Native. J'ai un magasin MobX, wordStore. Chaque modification de texte déclenche une requête de base de données via l'action setFilter. Tout cela fonctionne sous le capot comme je peux le voir à partir de la sortie de débogage de la console. Toutefois, le composant WordList semble disparaître dès que des mises à jour sont déclenchées, c'est-à-dire que si je définis une chaîne de filtre par défaut, les éléments correspondants s'affichent dans la liste, mais dès qu'un texte change, il disparaît.Le composant disparaît à la mise à jour

Y at-il quelque chose qui me manque? La chose étrange est la méthode WordList.render() est exécutée même si elle n'est pas visible.

EDIT: Rendu méthode .toString() du tableau fonctionne très bien à partir du composant contenant, mais étrangement sur itérer le tableau affiche également le même comportement, disparaissant sur la mise à jour.

Le composant contenant:

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

    } 
    // ... 
}); 

et le composant WordList:

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

À quoi ressemble la fenêtre de la console après avoir démarré l'application, puis modifié le filtre? Avez-vous vérifié que 'getWords()' fonctionne comme il se doit? – Glubus

+0

@Glubus oui tout fonctionne comme il se doit, la sortie console affiche les résultats mis à jour, et aussi la sortie de 'words.toString()' dans le composant contenant est mis à jour comme prévu – Adamski

Répondre

9

Ce fut une erreur stupide. Cela était dû au fait que flex n'était pas défini dans la vue contenant. Le code correct pour l'exemple ci-dessus:

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

Merci. J'ai eu un problème similaire lorsqu'un composant n'était pas rendu parce que l'un de ses parents dans la hiérarchie n'avait pas de «flex: 1». –