【问题标题】:I can't remove items from FlatList by useState hook我无法通过 useState 挂钩从 FlatList 中删除项目
【发布时间】:2020-03-05 18:08:46
【问题描述】:

我试图通过单击每个项目来删除 FlatList 中的项目,但这对我不起作用,当我单击每个项目时没有任何反应并且我没有收到任何错误。 我该如何解决这个问题?

这是我的代码:(我删除了不必要的代码和样式)

const FoodList = () => {


  const data=  [

        { text: 'test' },
        { image: 'https://via.placeholder.com/200x100' },
        { text: 'test' },
        { text: 'test' },
        { text: 'test' },
        { text: 'test' },
        { text: 'test' },
        { text: 'test' },
        { text: 'test' },

    ]




    let [itemState, setitemState] = useState(data);




    return (


        <View>
            <FlatList
                data={data}
                keyExtractor={(item, index)=>index}
                renderItem={({ item }) => (
                    <TouchableOpacity>

                <View>
                        <Text>{item.text}</Text>
                        <Image source={{ uri: item.image}}
                        />
                    </View>
                    <Icon  
                 onPress={(index)=>setitemState(itemState=itemState.filter(item=>item.index!==index))} />
                    </TouchableOpacity>
                )}
 />
 </View>
    )}

【问题讨论】:

  • item 好像没有索引,所以item.index!==index 用处不大。
  • 那么解决办法是什么?
  • 试试setitemState(itemState =&gt; itemState.filter((item, itemIndex) =&gt; itemIndex !== index))
  • 谢谢哥们,它有效,但是在点击 touchableopacity 后它会删除平面列表中的所有项目,我希望它只删除一项。

标签: javascript reactjs react-native react-hooks react-native-flatlist


【解决方案1】:

首先,正如@Hamza Khattabi 所说,您需要在data 属性中使用itemState 才能真正使用更新状态,否则使用setitemState 没有意义,它只修改了@987654326 @状态。

其次,我认为item.index 根本不会返回任何内容,而且我非常有信心您的Icon 元素中的onPress={(index) =&gt; {...}} 也不会返回任何index您将可以使用来自renderItem 属性的index,如this link 的文档中所述。

考虑到这些更改后,您可以简单地过滤掉 itemState 状态以删除索引处的元素。有许多不同的方法可以删除索引处的元素,但这里有一个可能的解决方案:

<FlatList
  data={itemState} // Note the use of itemState
  keyExtractor={(item, index) => index}
  renderItem={({ item, index }) => ( // Note the use of index
    <TouchableOpacity>
      <View>
        <Text>{item.text}</Text>
        <Image source={{ uri: item.image }} />
      </View>
      <Icon
        onPress={() => { // Note that here you can use any function to remove the element at index from the itemState list
          let _itemState = itemState.filter(
            (_item, _index) => _index !== index
          );
          setitemState(_itemState);
        }}
      />
    </TouchableOpacity>
  )}
/>

如果这对您有帮助,请在下面发表评论。

【讨论】:

  • 感谢哥们的帮助,但是我在VScode中遇到错误,似乎无法在onPress事件中声明变量,有什么解决办法吗?
  • 抱歉,我没有注意到您已经更改了 onPress 语法,它有效,但它可以一键将所有项目删除到 FlatList 中
  • 让我看看是否可以在 codepen 中重现此内容并回复您。这可能是我可能错过的非常小的事情,对此我深表歉意。
  • 我刚刚注意到您的代码还有一个问题,您使用的 TouchableOpacity 没有任何 onPress 属性。如果您不需要onPress,请将其更改为View而且您还使用IcononPress,如果我假设您使用react-native-vector-icons 他们没有onPress 属性。请确保检查 onPress 道具是否可用
  • 好的,这里是小吃链接:snack.expo.io/Skh5VfyS8。如您所见,我的解决方案非常好,只是我忽略了没有任何道具的TouchableOpacity,以及带有onPressIcon。在这个 Snack 中,我只进行了这些更改以表明逻辑没问题。您只需要确保组件中存在相关的道具。 Icons 通常有一个 name 强制属性,您的代码中缺少该属性。我将在上面更新我的答案以反映这些变化。如果这有助于您解决问题,请将问题标记为已解决。
【解决方案2】:

用你的状态替换数据属性中的数据变量

const FoodList = () => {


    ...


    let [itemState, setitemState] = useState(data);




    return (


        <View>
            <FlatList
                data={itemState}
                keyExtractor={(item, index)=>index}
                renderItem={({ item }) => (
                 ...
 </View>
    )}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多