2
votes

React Native: FlatList ne s'affiche pas

J'essaie de créer un composant personnalisé qui affichera des options pour un nouveau choix si le premier choix n'est pas assez clair. J'utilise le composant FlatList pour afficher les données et il semble ne pas afficher les données fournies comme accessoire.

C'est la fonction render pour le composant

"c_node_name_scientific": "Centurio",
"c_syn_name": "wrinkle-faced bat",
"i_node_id": 27644,

Ceci est le composant PickerBox

import PickerBox from "./PickerBox"; // reside in same folder

Ceci est l'instruction d'importation pour le PickerBox dans le composant

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: "row",
    padding: 10,
    marginLeft: 16,
    marginRight: 16,
    marginTop: 8,
    marginBottom: 8,
    borderRadius: 5,
    backgroundColor: "#FFF",
    elevation: 2
  },
  title: {
    fontSize: 16,
    color: "#000"
  },
  container_text: {
    flex: 1,
    flexDirection: "column",
    marginLeft: 12,
    justifyContent: "center"
  },
  description: {
    fontSize: 11,
    fontStyle: "italic"
  }
});

const PickerBox = (title) => {
  return (
    <View style={styles.container}>
        <Text style={styles.container_text}>{title}</Text>
    </View>
  );
};

export default PickerBox;

L'état dataSource provient d'un objet JSON qui contient une disposition comme celle-ci dans chaque entrée.

import { Header, List, ListItem } from "react-native-elements";
import PickerBox from "./PickerBox";

render() {
    return (
      <View>
        <Header
          centerComponent={{
            text: "By " + this.state.newTaxon + ", did you mean...",
            style: { color: "white", fontSize: 20, textAlign: "center" }
          }}
          backgroundColor="black"
        />
        <FlatList
          data = {this.state.dataSource}
          renderItem = {({item}) => {
            <PickerBox
              title = {item.c_syn_name}
            />
          }}
          keyExtractor = {(item) => item.c_syn_name}
        />
      </View>
    );
}

La sortie dans le simulateur est juste l'en-tête, mais la sortie attendue est l'en-tête avec la liste en dessous.


2 commentaires

veuillez ajouter des styles dans PickerBox


J'ai ajouté les styles.


3 Réponses :


0
votes

vous pouvez essayer ceci

   renderItem = {({item}) => {
            PickerBox(item.c_syn_name);
          }}


0 commentaires

0
votes

Tout d'abord, veuillez vous assurer que this.state.dataSource n'est pas un tableau vide. Si votre dataSource est quelque chose comme ça, alors cela devrait fonctionner:

<FlatList 
    data={[{c_syn_name: 'a'}, {c_syn_name: 'b'}]}
    keyExtractor = {item => item.c_syn_name}
    renderItem={({item}) =><PickerBox title = {item.c_syn_name} />}
    />


0 commentaires

5
votes

Premièrement, vous devez vous assurer que si votre méthode renderItem utilise une fonction de grosse flèche avec des accolades comme vous l'êtes dans votre exemple, vous devez ajouter un retour instruction comme ceci:

<FlatList
  data={Object.keys(this.state.dataSource)}  // will result in ["key1", "key2", "key3"]
  renderItem={({item}) => 
    // here `item` will be the Object's key. eg: "key1"
    <PickerBox title={this.state.dataSource[item].title} />
  }
/>

Si vous n'utilisez pas d'accolades, vous pouvez définir la fonction comme ceci:

{
  key1: {title: 'Title 1'},
  key2: {title: 'Title 2'}
  key3: {title: 'Title 3'}
}

Deuxièmement, assurez-vous que les données sont un tableau et non un objet . Selon la description de la propriété data de FlatList dans la documentation react-native :

Pour simplifier, les données ne sont qu'un simple tableau. Si vous souhaitez utiliser autre chose, comme une liste immuable, utilisez directement la VirtualizedList sous-jacente.

D'après votre question, il semble que vous vouliez parcourir un tableau d'objets similaire à celui-ci:

[
  {
    "c_node_name_scientific": "Centurio",
    "c_syn_name": "wrinkle-faced bat",
    "i_node_id": 27644
  },
  {
    "c_node_name_scientific": "xxx",
    "c_syn_name": "xxx",
    "i_node_id": 123
  },
  //...
]

Si tel est le cas, enveloppez simplement l'objet dataSource de l'état dans un tableau comme illustré ci-dessus.

Si vous souhaitez transmettre les données sous la forme d'un objet similaire à celui-ci:

renderItem={({item}) => <PickerBox title={item.c_syn_name} />}

vous devrez faire quelque chose comme ce qui suit pour rendre les données accessibles à la FlatList:

renderItem={({item}) => { return <PickerBox title={item.c_syn_name} /> }}

Et enfin, si la Flatlist doit mise à jour au fur et à mesure que l'état se met à jour, vous devez ajouter le prop extraData = {this.state} à la FlatList. Conformément à la Documentation FlatList :

En passant extraData = {this.state} à FlatList, nous nous assurons que FlatList lui-même sera de nouveau rendu lorsque le state.selected change. Sans définir cet accessoire, FlatList ne saurait pas qu'il a besoin de restituer les éléments car il s'agit également d'un PureComponent et la comparaison d'accessoires ne montrera aucun changement.


4 commentaires

Pour votre première partie, si je supprime les accolades ou ajoute une déclaration de retour dans les accolades. J'obtiendrai une erreur avec le message indiquant console.error: `` Exception JS non gérée: violation invariante: les objets ne sont pas valides en tant qu'enfant React (trouvé: objet avec les clés {titre}). Si vous vouliez rendre une collection d'enfants , utilisez plutôt un tableau.


Si j'ignore les accolades, j'obtiendrai alors le message d'avertissement de chaque enfant de la liste devrait avoir un accessoire de clé unique et rien ne sera rendu.


@ dpatel125 supprime les accolades et les remplace par des parenthèses. ()


en ce qui concerne le problème clé, regardez l'ajout de la prop keyExtractor à la FlatList et utilisez quelque chose comme ceci item. i_node_id} />