skip to Main Content

React Native List with Map Method

What I want to achieve,
I want when click item then a new Item (I preferer add a new custom View) is added below the Selected item.

Expo Snack code>
https://snack.expo.dev/@stefanosalexandrou/tenacious-french-fries

enter image description here

2

Answers


  1. There are some points to consider and I’ll list them here, before providing an idea of a solution:

    • React Native provides performance-optimized components that handle list rendering named <FlatList />/<SectionList />. Use those components instead of .map() for rendering component lists
    • You’ll need to create an internal state for your list to be changed
    • You need to provide a key prop when rendering a list of components using .map() or other Array methods

    With minimal changes to your provided code, you can create a state to store the list and when the item is pressed you can insert a new item inside this list:

    import React, { useState } from "react";
    import { Text, View, StyleSheet, ScrollView, TouchableOpacity } from 'react-native';
    
    const people = [/* your list */];
    
    export default function App() {
      const [peopleList, setPeopleList] = useState(people)
      const [selectedId, setSelectedId] = useState(null);
    
      return (
        <View style={styles.container}>
          <ScrollView>
            <View>
    
              {list.map((person, index) => {
                return (
                  <TouchableOpacity 
                  onPress={() => {
                    setSelectedId(person.id)
                    const newPerson = {...person}; // The new item
                    setPeopleList((prevList) => [...prevList.slice(0,index + 1), newPerson, ...prevList.slice(index + 1)])
                  }}
                  style={{
                    padding:20,
                    backgroundColor: backgroundColor,
                    marginBottom:20,
                  }}
                  >
                    <Text>{person.name}</Text>
                  </TouchableOpacity>
                );
              })}
            </View>
          </ScrollView>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        padding:20
      }
    });
    

    Sandbox with working code: https://snack.expo.dev/5rvTbrEvO

    Login or Signup to reply.
  2. Since you are changing the background of the selected item, it is necessary that you update the ID’s of every item in the list, for otherwise inserting elements will break this functionality. Furthermore, you need to add a state for for otherwise you cannot trigger a UI change

    You could implement the desired behaviour as follows.

      const [selectedId, setSelectedId] = useState(null);
      const [data, setData] = React.useState(persons)
    
      function handleOnPress(idx) {
        setSelectedId(idx)
        const first = data.slice(0, idx + 1);
        const second = data.slice(idx + 1).map(p => ({...p, id: Number(p.id) + 1}));
        setData([...first, {id: idx + 2, name: "Whatever new iten"}, ...second])
      }
    
      return (
        <View style={styles.container}>
          <ScrollView>
            <View>
    
              {data.map((person, index) => {
    
                const backgroundColor = index === selectedId ? "#6e3b6e" : "#f9c2ff";
    
                return (
                  <TouchableOpacity 
                  onPress={() => handleOnPress(index)}
                  style={{
                    padding:20,
                    backgroundColor: backgroundColor,
                    marginBottom:20,
                  }}
                  >
                    <Text>{person.name}</Text>
                  </TouchableOpacity>
                );
              })}
            </View>
          </ScrollView>
        </View>
      );
    

    Use slice in order to split the array into two parts. Use map for updating the id attribute of the elements in the second array. Finally, combine both parts but insert a new element between them.

    Here is an updated snack.

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