Reputation: 1527
I want to render object with React Native's FlatiList but this component doesn't return the expected result. My dictionary is like this:
Object {
"Lisa.Sky": Object {
"name": "Lisa",
"surname": "Sky",
"age": 21,
"sex": female
},
"Thomas.Prat": Object {
"name": "Thomas",
"surname": "Prat",
"age": 33,
"sex": male
},
"Paul.Sing": Object {
"name": "Paul",
"surname": "Sing",
"age": 88,
"sex": male
},
"Andrew.Brown": Object {
"name": "Andrew",
"surname": "Brown",
"age": 23,
"sex": male
},
}
I have implemented a FlatList like this, but I have white screen
<View>
<ScrollView>
<FlatList
data={this.props.nameList}
renderItem={({item}) =>
<View key={item.name + "." + item.surname}>
<Text style={styles.viewDetail}>{item.name}</Text>
<Text style={styles.viewDetail}>{item.surname}</Text>
<Text style={styles.viewDetail}>{item.age}</Text>
<Text style={styles.viewDetail}>{item.sex}</Text>
</View>
}
keyExtractor={(index) => index.toString()}
/>
</ScrollView>
</View>
Thanks
Upvotes: 10
Views: 20479
Reputation: 632
I wrote following utility function to convert tree data into flat array of objects:
const isLiteralObject = (a) => {
return !!a && a.constructor === Object;
};
/**
* Utility to convert tree data into flat array of object to be used
* to render lists
*
* @param obj - JSON/JS object
* @param idField item identifier to be used as parent ID for children nodes
* @param level - level in tree starting with 1
* @param parent - parent ID to be set to children (extracted based on given idField)
* @returns Array<any>
*/
const objectToFlatArray = (obj, idField = 'id', level = 0, parent = '') => {
if (!isLiteralObject(obj)) {
return obj;
}
let arr = [];
const isValidNode = Object.values(obj).some((item) => !isLiteralObject(item));
const nextLevel = isValidNode ? level + 1 : level;
const nObj = { __level__: nextLevel, __parent__: parent };
for (const k in obj) {
if (isLiteralObject(obj[k])) {
arr = arr.concat(
objectToFlatArray(obj[k], idField, nextLevel, obj[idField] || parent)
);
} else {
nObj[k] = obj[k];
}
}
Object.keys(nObj).length > 2 && arr.unshift(nObj);
return arr;
};
console.log(objectToFlatArray({
'Lisa.Sky': {
name: 'Lisa',
surname: 'Sky',
age: 21,
sex: 'female',
},
'Thomas.Prat': {
name: 'Thomas',
surname: 'Prat',
age: 33,
sex: 'male',
},
'Paul.Sing': {
name: 'Paul',
surname: 'Sing',
age: 88,
sex: 'male',
},
'Andrew.Brown': {
name: 'Andrew',
surname: 'Brown',
age: 23,
sex: 'male',
},
}))
Upvotes: 0
Reputation: 283
I got to this old post because I googled "flatlist react native support object" and in turns out - FlatList only supports array. But the underlying VirtualizedList do support object.
My data is structured by recommendations from redux:
const data = {
byId: {
0: { id: '0', name: 'Bill' },
1: { id: '1', name: 'Steve' },
2: { id: '2', name: 'Dan' },
},
allIds: [0, 1, 2]
};
And i need VirtualizedList to support this data structure
<VirtualizedList
// Use keyExtractor to help the list optimize performance
keyExtractor={item => item.id}
data={data}
initialNumToRender={7}
renderItem={({item})=> {
return <Text>{item.name}</Text>;
}}
// the virtualized list doesn't know how you want to extract your data
// you need to tell it
getItem={(data, index) => {
const dataIndex = data.allIds[index];
return data.byId[dataIndex];
}}
// it also needs to know how much data you have
getItemCount={data => data.allIds.length}
/>
The difference between the FlatList implementation and the VirtualizedList is just you need to overwritegetItem and getItemCount
You can see full example here: https://snack.expo.io/@rcknti/virtualized-list-example
Upvotes: 2
Reputation: 3548
You need to use your data as an array(If you need, you can check that from https://facebook.github.io/react-native/docs/flatlist#data ). Your data can be something like that,
const nameList = [
{
"name": "Lisa",
"surname": "Sky",
"age": 21,
"sex": female
},
{
"name": "Thomas",
"surname": "Prat",
"age": 33,
"sex": male
},
{
"name": "Paul",
"surname": "Sing",
"age": 88,
"sex": male
},
{
"name": "Andrew",
"surname": "Brown",
"age": 23,
"sex": male
},
];
Upvotes: 1
Reputation: 1588
you can do like this way. check working snack. https://snack.expo.io/@nazrdogan/bad-cashew
import * as React from 'react';
import { Text, View, StyleSheet, FlatList } from 'react-native';
import { Constants } from 'expo';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
var obj = {
'Lisa.Sky': {
name: 'Lisa',
surname: 'Sky',
age: 21,
sex: 'female',
},
'Thomas.Prat': {
name: 'Thomas',
surname: 'Prat',
age: 33,
sex: 'male',
},
'Paul.Sing': {
name: 'Paul',
surname: 'Sing',
age: 88,
sex: 'male',
},
'Andrew.Brown': {
name: 'Andrew',
surname: 'Brown',
age: 23,
sex: 'male',
},
};
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<FlatList
data={Object.keys(obj)}
renderItem={({ item }) => <Text>{obj[item].name}</Text>}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
});
Upvotes: 34
Reputation: 6393
According to documentation
For simplicity, data is just a plain array. If you want to use something else, like an immutable list, use the underlying
Try to pass data as array not object
Upvotes: 2