如何从 React Native 的 FlatList 中删除一个项目/索引?

14
我有一段数据,已经被呈现为视图,并遇到了一个问题,如何删除已划掉的特定索引。我已经使用如下的FlatList:
render() {
this.leftOpenValue =  Dimensions.get('window').width;
this.rightOpenValue = -Dimensions.get('window').width;

return (   

     <FlatList 
            data = {data}  
            keyExtractor = {data => data.id}                
            renderItem={ ({item}) => (

                <View style={styles.container}>
                    <SwipeView            
                        disableSwipeToRight = {false}
                        renderVisibleContent={() => 
                            <View>
                                <Text style={styles.text}> {item.title} </Text>     // This repeats 9 times (9 Index)              
                            </View>          
                        }
                        renderRightView={() => (
                            <View style={{flex:1, justifyContent: 'flex-end', alignItems: 'center', backgroundColor: 'red'}}>

                            </View>
                        )}

                        leftOpenValue = {this.leftOpenValue}
                        rightOpenValue = {this.rightOpenValue}
                        onSwipedLeft={() => alert("deleted")}
                        swipeDuration = {300}
                        swipeToOpenPercent = {40}
                        disableSwipeToRight = {true}
                    />
                </View>  

            )}
    />
);

我使用了Swipeview进行滑动操作(react-native-swipeview)并在flatlist中删除索引。

我遇到了如何从flatList中删除项目的问题。


3
您写了哪些代码来尝试删除列表或数据中的某一项?通常的模式是将一个唯一标识符(键、索引等)传递给您的“删除项目”回调函数,并在数值上过滤掉不等于该键的数据。这将返回一个新数组,不包含该条目,您需要将其存储回状态中。 - Drew Reese
3个回答

30

通常的模式是将一个唯一标识符 id(键、索引等)传递给您的删除处理程序,并在值不等于该键的情况下过滤数据。这将返回一个没有该条目的新数组以存储在状态中。

deleteItemById = id => {
  const filteredData = this.state.data.filter(item => item.id !== id);
  this.setState({ data: filteredData });
}

render() {
  ...

  return (   
    <FlatList 
      data={data} // Assuming this is `this.state.data`
      keyExtractor={({item}) => item.id}                
      renderItem={({item}) => (
        <View style={styles.container}>
          <SwipeView
            ...
            onSwipedLeft={() => this.deleteItemById(item.id)}
            ...
          />
        </View>  
      )}
    />
  );
}

使用柯里化函数处理程序。这样可以通过将回调函数设置为事件处理程序并将id封闭在函数作用域中来避免使用匿名回调。

deleteItemById = id => () => {
  const filteredData = this.state.data.filter(item => item.id !== id);
  this.setState({ data: filteredData });
}

render() {
  ...

  return (   
    <FlatList 
      data={data} // Assuming this is `this.state.data`
      keyExtractor={({item}) => item.id}                
      renderItem={({item}) => (
        <View style={styles.container}>
          <SwipeView
            ...
            onSwipedLeft={this.deleteItemById(item.id)}
            ...
          />
        </View>  
      )}
    />
  );
}

有没有更快的替代方法来查找要删除的项目,而不是使用.filter()遍历整个列表? - Raphael
1
@iamfrank 你可以传递一个索引然后将其切片,但是因为你仍然需要返回一个新数组(包含其他元素),所以时间复杂度依然相同,即从数组中删除一个元素并返回一个新的数组引用是一种 O(n) 操作。以上我们并没有真正使用 filter 来“查找”元素,主要是为了返回一个新数组。 - Drew Reese
@famfamfam,我不太明白你的评论。那是一个问题吗?如果这不仅是一个琐碎的问题,最好在stackoverflow上提出一个关于你具体问题/问题的新问题。如果您正在处理或尝试实现某些内容,可以参考此答案。请随时在此处的评论中ping(@我)并附上您的帖子链接,我会尽快查看。 - Drew Reese
在这个方法中,图片会在平面列表上被重新绘制,因为它们的位置在移除一个项目后发生了改变。有没有更好的方法可以移除项目,使得图片不会重新出现在列表上,而是简单地移动到新的位置呢? - CrackerKSR
@CrackerKSR 对于“在平面列表上重新绘制图像,因为它们的位置在删除项目后发生了变化”这一点我不太清楚你具体是什么意思。你能澄清一下吗?此外,你的问题是否与从数组中删除项目有关,还是更多地涉及某个子组件/元素等的渲染问题?无论哪种情况,最好在SO上提出一个新问题。如果你这样做了,请在评论中@我并附上问题链接,我会尽快查看。 - Drew Reese

3
将项目的ID传递给 onSwipeLeft={this.deleteItem(item.id)} 并使用 setState 更新数据。
state = {
    data: [{
      title: 'Hello world',
      id: 'hello'
    },{
      title: 'World says hello',
      id: 'say'
    }]
}

deleteItem = (id) => {

   this.setState({
    data: this.state.data.filter(item => item.id !== id)
   })

}

嘿,谢谢,这对我很有效。我还有另一个问题,会导致问题,请你看一下这个问题:this - Oliver D
通过这种方法,目标项(要删除的项)后面的图像项会在平面列表上重新绘制。有没有更好的方法来避免这个问题? - CrackerKSR

0

先执行普通的对象删除,然后过滤您的状态以进行清理。

 let _rem = this.state.data;
 delete  _rem[index_no];
 this.setState({data: this.state.data.filter(args=>args!==index_no)});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接