anyone know how to make a flatlist reset id number after I remove 1 item from it

378 views Asked by At

like my title said I struggle with this though below is a example

{ id: '1', name: 'one' },
    { id: '2', name: 'two' },
    { id: '3', name: 'three' },
    { id: '4', name: 'four' },

this is a flatlist after I remove item with id '2' I want id 3 become 2 and id 4 become 3 so the flatlist after id 2 be removed will like

{ id: '1', name: 'one' },
        { id: '2', name: 'three' },
        { id: '3', name: 'four' },

here is my code

export default function Listdata({ route }) {
    const [itemData, newItem] = React.useState([]);

    const [itemState, setItemState] = React.useState(itemData);
    const [idmoi, incr,] = React.useState(1);
    const [textNhapVao, setTextNhapVao] = React.useState('');


    const tinhToanId = (t) => {
        var idNew = [itemData.id];
        incr(idNew - 1);
    }


    const themItem = () => {
        var arrayMoi = [...itemData, { id: idmoi, name: textNhapVao }];
        incr(idmoi + 1)
        console.log('idddd')
        console.log(idmoi)
        setItemState(arrayMoi);
        newItem(arrayMoi);
    }
    <View>

    </View>

    const keyboardVerticalOffset = Platform.OS === 'ios' ? 40 : 0

    const xoaItem = (IItem) => {
        console.log('routeeee')
        console.log(route.params.paramKey)
        setItemState(prevItemState => prevItemState.filter((_item, _Index) => _Index !== IItem));
    }
    return (
        <Container style={styles.container}>
            <View style={{
                alignItems: 'center',
                justifyContent: 'center',
                borderBottomWidth: 1,
                borderColor: '#d7d7d7',
            }}>
                <Text style={{ fontWeight: 'bold', fontSize: 30, color: 'green' }}>Xin Chào {route.params.paramKey}</Text>
            </View>
            <FlatList
                data={itemState}
                keyExtractor={(item, index) => index}
                renderItem={({ item, index }) => (
                    <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
                        <View style={{ marginLeft: 20 }}>
                            <Text style={{ fontSize: 30, color: 'red' }} >{item.id}{'\n'}{item.name}</Text>
                        </View>
                        <View style={{ justifyContent: 'center', marginRight: 20 }}>
                            <TouchableOpacity
                                style={{
                                    width: '100%',
                                    backgroundColor: 'red',
                                }}
                                activeOpacity={0.7}
                                onPress={() => xoaItem(index)}
                            >
                                <IconFE name='trash-2' size={30} style={{ color: 'orange' }} />
                            </TouchableOpacity>
                        </View>
                    </View>
                )}
            />
            <View
                style={{
                    position: 'relative', height: 50,
                    borderTopWidth: 1,
                    borderColor: '#d7d7d7',
                }}>
                <KeyboardAvoidingView enabled behavior={Platform.OS === "ios" ? "padding" : null} keyboardVerticalOffset={keyboardVerticalOffset} >
                    <View
                        style={{
                            alignItems: 'center', position: 'relative',
                            flexDirection: 'row',
                            justifyContent: 'space-between',
                            marginLeft: 20,
                            marginRight: 20,
                        }}>
                        <Input
                            onChangeText={data => setTextNhapVao(data)}
                            placeholder='Nhập Vào Đây'></Input>
                        <TouchableOpacity
                            title="Thêm"
                            onPress={themItem}>
                            <IconFE name='check-square' size={30} style={{ color: 'blue' }} />
                        </TouchableOpacity>
                    </View>
                </KeyboardAvoidingView>
            </View>
        </Container>
    )
}

and below is my screenshot flatlist: https://uphinh.org/image/9OLoCN

4

There are 4 answers

7
Nina Scholz On BEST ANSWER

You could take a function which removes the object at the given index.

The function takes the removed array, takes the object at start and gets the id then it loops from the index until the end and updates all id properties.

const
    remove = (array, index) => {
        let removed = array.splice(index, 1);

        if (!removed.length) return array;
        let id = +removed[0].id;
        while (index < array.length) array[index++].id = (id++).toString();
        return array;
    },
    data = [{ id: '1', name: 'one' }, { id: '2', name: 'two' }, { id: '3', name: 'three' },  { id: '4', name: 'four' }];

remove(data, 1);

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

3
DecPK On

You can easily achieve this result

  • Find the index of the element that you want to remove using findIndex
  • Then divide the array into two halves
  • Add one to the second array after it is parsed to int.
  • join the array.
  • Be sure to cover the corner case if the element is not in arr.

const arr = [
  { id: "1", name: "one" },
  { id: "2", name: "two" },
  { id: "3", name: "three" },
  { id: "4", name: "four" },
];

function resetIds(arr) {
  return arr.map((o) => {
    return { ...o, id: `${parseInt(o.id) - 1}` };
  });
}

const id = "2";
const elementToRemoveIndex = arr.findIndex((o) => o.id === id);

const result =
  elementToRemoveIndex !== -1
    ? [
        ...arr.slice(0, elementToRemoveIndex),
        ...resetIds(arr.slice(elementToRemoveIndex + 1)),
      ]
    : [...arr];

console.log(result);

1
ulou On

As far as I understand your id is not continues (1,2,3...), because if so, you don't need to mutate id at all, you can just use array indices instead. Anyway, if you assume that id is not continues, we can try following algorithm:

  • Find remove index,
  • Map element n to n+1 for indices higher than remove index,
  • Remove last element (it will be our final remove item, that has been pushed to the end).

Code example:

const data = [
    { id: '1', name: 'one' },
    { id: '2', name: 'two' },
    { id: '5', name: 'five' },
    { id: '6', name: 'six' }]
    
    
const removeFromArr = (arr, name) => {
  const removeIdx = arr.findIndex(e => e.name === name)
  return arr.map((e, i, a) => removeIdx <= i ? ({...e, name: a?.[i + 1]?.name}) : e) // map element n to n+1 if higher than remove idx
            .slice(0, arr.length - 1) // remove last item
}
 
const newData = removeFromArr(data, "two")
 
console.log(newData)
.as-console-wrapper { max-height: 100% !important; top: 0; }

5
Pramod On

From the provided array remove the selected array by splice method by finding its index

Working example: https://snack.expo.io/@msbot01/137768

import React, { Component } from 'react';
import {View, Text, StyleSheet, Image, TouchableOpacity, Dimensions, FlatList} from 'react-native';

export default class SupervisorDashboard extends Component<Props> {

 constructor(props) {
    super(props);
    this.state = { 
      userData:[
                {id:1, name:"One"},
                {id:2, name:"Two"},
                {id:3, name:"Three"},
                {id:4, name:"Four"},
                {id:5, name:"Five"},
                {id:6, name:"Six"},
              ]
      
     
    }    
  }

  componentDidMount(){
    
  }


  removeItem(index){
    this.state.userData.splice(index, 1);
    var array = []
    // console.log(JSON.stringify(this.state.userData))
    for(var i=0; i< this.state.userData.length; i++){
      var eachElement = {id: (i+1), name: this.state.userData[i].name }
      array.push(eachElement)
    }
    console.log(JSON.stringify(array)) 

    this.setState({}) 
  }

  renderItem(item, index){
    // console.log(item.id) 
    return(
      <View style={{height:60, width:'90%', marginTop:10, marginLeft:'5%', marginRight:'5%', flexDirection:'row', justifyContent:'space-between', alignItems:'center', borderRadius:10, borderWidth:1, borderColor:'#ececec', padding:10}}>
        <Text>{item.id}</Text>
        <Text>{item.name}</Text>
        <TouchableOpacity onPress={()=>{this.removeItem(index)}} style={{marginRight:10, backgroundColor:'grey', height:'100%', justifyContent:"center", borderRadius:10, padding:10}}>
            <Text>Click to remove</Text>
        </TouchableOpacity>
      </View>
    )
  }
 
  
  render(){
    return(
      <View style={{flex:1, backgroundColor:'white'}}>
                <FlatList
                data={this.state.userData}
                renderItem={({ item, index })=>this.renderItem(item, index)}
                keyExtractor={item => item.id}
              />
        
      </View>
    );
  }

}

const styles = StyleSheet.create({
  background: {
    backgroundColor: 'red'
  }
});