skip to Main Content

I have a problem that I cannot solve.
I have a string of objects which in turn has another string of objects

const data = [
        {
            title: 'Medical',
            data: [{
                notice: 'Test 1',
                documentType: 'Medical',
                file: 'https://test.1'
            }],
        }
    ];

And I try to load in a scroll view component those items according to the title

<View>
            <Header title={PERSONAL_INFO}/>
            <Center>
                <ScrollView w={["200", "300"]} h="80">
                    {data.map((item, index) => (
                        (<View>
                            <Center>
                                <Heading>
                                    {item.title}
                                </Heading>
                                {
                                    data[index].data.map((item) =>
                                        <Text>{item.notice}</Text>
                                    )
                                }
                            </Center>
                        </View>)
                    ))}
                </ScrollView>
            </Center>
        </View>

Everything loads correctly with only one condition, I get a warning that I can’t get rid of.

 Warning: Each child in a list should have a unique "key" prop.

3

Answers


  1. Try mapping over item.data

            <View>
              {data.map((item, idx) => ( <---- first array
                <View key={idx}>
                  <Text style={{ fontSize: 40 }}>{item.title}</Text>
                    {item.data.map((subItem, key) => ( <--- inner array
                  <View key={key}>
                    <Text style={{ fontSize: 20 }}>{subItem.notice}</Text>
                    <Text style={{ fontSize: 20 }}>{subItem.documentType}</Text>
                    <Text style={{ fontSize: 20 }}>{subItem.file}</Text>
                  </View>
                    ))}
                </View>
              ))}
            </View>
    
    Login or Signup to reply.
  2. When rendering a list of items using React, each element should be given a unique key. These keys allow React to update its component tree more efficiently by providing it a way to determine whether certain components have only moved and don’t need to be updated. The "Why does React Need Keys?" section in their beta docs has a good analogy for this.

    That being said, you just need to give each outermost component rendered inside each map a unique key.

    // Assuming your item has some unique identifier property...
    type Item = {
        id: string
    }
    
    // Example data array
    const data: Item[] = [
        { id: "first item" },
        { id: "second item" }
    ]
    
    <View>
        {data.map(item => (
            {/* key prop used here */}
            <View key={item.id}>
                {/* This doesn't need a key because it isn't the outermost
                    component rendered in the map
                */}
                <Text>Some example text</Text>
    
                {/* Anything can go in here, including another nested map.
                    Just make sure to give each element a unique key in that one as well.
                */}
            </View>
        ))}
    </View>
    

    Also note that React docs recommend against using the index as a key (see end of section).

    Login or Signup to reply.
  3. You need to give keys to the top level container of each item that you return when you’re mapping, e.g. View and Text

    <View>
                <Header title={PERSONAL_INFO}/>
                <Center>
                    <ScrollView w={["200", "300"]} h="80">
                        {data.map((item, index) => (
                            (<View key={index}>
                                <Center>
                                    <Heading>
                                        {item.title}
                                    </Heading>
                                    {
                                        data[index].data.map((item, idx) =>
                                            <Text key={idx}>{item.notice}</Text>
                                        )
                                    }
                                </Center>
                            </View>)
                        ))}
                    </ScrollView>
                </Center>
            </View>
    

    it would be far more ideal if you had Ids to reference, as using index as a key is an anti-pattern. but it’s probably okay for your use case.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search