I'm trying to use a SectionList to print the key/value pairs of an object. However, values which are strings are rendered character by character by the renderItem.
Code:
const mainObject = {
"key1": "val1",
"key2": ["val2.0","val2.1"],
"key3": "val3",
}
const renderItem = ({item}) => <Text>{item}</Text>
const sectionHeader = ({section}) => (
<Text style={{fontWeight: "bold"}}>{section.title}</Text>);
//Object.entries(obj) returns an array [["key0","value0"],["key1","value1"]
//for all the key value pairs in the object
const sections = (obj) => Object.entries(obj).map((val) => ({
data: val[1],
title: val[0],
}))
const ObjectList = props => (
<SectionList
renderItem={renderItem}
renderSectionHeader={sectionHeader}
sections={sections(mainObject)}
keyExtractor={(item, index) => item + index}
>
</SectionList>
)
The output on the screen is:
key1
v
a
l
1
key2
val2.0
val2.1
key3
v
a
l
3
To fix the problem, I have put the strings into Arrays and so Strings inside arrays are printed properly, but I was just wondering why they need to be nested inside an array for the whole string to be printed on on one row?
const sections = (obj) => Object.entries(obj).map((val) => ({
//checks if the value is an array, if not then nest that value
//inside the array otherwise leave it as it is
data: !Array.isArray(val[1]) ? [val[1]] : val[1],
title: val[0],
}))
The data
key in the sections
prop is expected to be a list of items to render in the section
. Your code above ends up with something like:
const sections = [
{title: 'key1': data: 'val1'},
...
]
when val[1]
is a string.
So the SectionList
is iterating over data
, which is just a string, to create each item under that section heading, hence you get each character. If val[1]
may be a string or may be an array of strings then you're doing the correct thing by wrapping it in an array if necessary.
If you have control over how mainObject
is created you probably want to wrap the vals beforehand:
const mainObject = {
"key1": ["val1"],
"key2": ["val2.0","val2.1"],
"key3": ["val3"],
}