Home > other >  React Native List with Map Method add New Item below selected Item
React Native List with Map Method add New Item below selected Item

Time:11-11

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> enter image description here

CodePudding user response:

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

CodePudding user response:

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.

  • Related