简体   繁体   English

React Native FlatList 项目消失

[英]React Native FlatList Items Disappearing

I have a Modal that the user selects categories from, and then that category loads into a FlatList on their profile page.我有一个模式,用户从中选择类别,然后该类别加载到他们的个人资料页面上的 FlatList 中。 When the first category is selected, it loads properly with the desired formatting:选择第一个类别后,它会以所需的格式正确加载:

在此处输入图像描述

When the user selects and adds a second item from the Modal, the items disappear, like so:当用户从 Modal 中选择并添加第二个项目时,这些项目会消失,如下所示:

在此处输入图像描述

And when a third item is added, this error is prompted:而当添加第三项时,会提示这个错误: 在此处输入图像描述

CODE :代码

Category array that the user is selecting from, and hook states:用户从中选择的类别数组和钩子状态:

const [catData, setCatData] = React.useState([])
const [catsSelected, setCatsSelected] = React.useState([])

const categoryData=[
    {
        id: 1,
        name: "CatOne",
    },
    {
        id: 2,
        name: "CatTwo",
    },
    {
        id: 3,
        name: "CatThree",
    }]

Function that is called once the user SELECTS the category they want:用户选择他们想要的类别后调用的函数:

const onSelectCategory = (itemSelected, index) => {
        let newData = categories.map(item => {
            if (item.id === itemSelected.id) {
                return {
                    ...item,
                    selected: !item.selected
                }
            }
            return {
                ...item,
                selected: item.selected
            }
        })
        selectedData = newData.filter(item => item.selected === true)
        setCatData(selectedData)
    }
// Note, the above code is as such due to initially wanting the user to be able to select multiple categories at a time, however,
// I've decided that one category at a time would suffice, and I just modified the above function to fit that need (I will tidy it up later).

Function called once user CONFIRMS the category that they've selected:用户确认他们选择的类别后调用的函数:

const catSave = () => {
        if(catData.length > 0){
            if(catsSelected.length < 1){
                setCatsSelected(catData)
            }
            else{
                testData = catsSelected
                testData = testData.push(catData[0])
                setCatsSelected(testData)
            }
        }
        setModalVisible(!modalVisible)
    }

And the FlatList that the selected categories are loaded into:以及所选类别加载到的 FlatList:

<FlatList 
   data={catsSelected}
   horizontal
   showsHorizontalScrollIndicator={false}
   keyExtractor={item => `${item.id}`}
   renderItem={renderCats}
                                    
/>

For reference, here is the console log of catsSelected as it is being modified:作为参考,这里是正在修改的catsSelected 的控制台日志:

[] // when it is initialized
[{"id": 1, "name": "CatOne", "selected": true}] // first item added
[{"id": 1, "name": "CatOne", "selected": true}, {"id": 2, "name": "CatTwo", "selected": true}] // second item added, the FlatList is now invisible
// Error prompts after third item is added.

What I require is for the FlatList to not be invisible, and for this error to not prompt after the third item is added, anyone sure as to why this occurs?我需要的是让 FlatList 不可见,并且在添加第三项后不提示此错误,有人确定为什么会发生这种情况吗?

Thanks for the assistance.感谢您的帮助。

Issue问题

  1. You are mutating state你正在改变状态
  2. You save the result of Array.prototype.push into state, which is the new array length, not the updated array您将Array.prototype.push的结果保存到 state 中,这是新的数组长度,而不是更新的数组
  3. On a subsequent render when catsSelected is no longer an array, but a number, the push method doesn't exist在后续渲染中,当catsSelected不再是数组而是数字时, push方法不存在

See Array.prototype.pushArray.prototype.push

The push() method adds one or more elements to the end of an array and returns the new length of the array. push()方法将一个或多个元素添加到数组的末尾,并返回数组的新长度。

const catSave = () => {
  if (catData.length > 0) {
    if (catsSelected.length < 1) {
      setCatsSelected(catData);
    } else {
      testData = catsSelected;              // <-- reference to state
      testData = testData.push(catData[0]); // <-- testData.push mutates state
      setCatsSelected(testData);            // <-- testData now new array length
    }
  }
  setModalVisible(!modalVisible);
}

Solution解决方案

Use a functional state update to correctly enqueue an update from the previous stat's array.使用功能状态更新从前一个统计数据的数组中正确地将更新排入队列。 Shallow copy the previous state's array and append the new data.浅复制先前状态的数组并附加新数据。

const catSave = () => {
  if (catData.length) {
    setCatsSelected(catsSelected => {
      if (catsSelected.length < 1) {
        return catData;
      }
      return [
        ...catsSelected,
        catData[0],
      ]
    });
  }
  setModalVisible(modalVisible => !modalVisible);
}

Looks like your issue is in the else statement in catSave function.看起来您的问题出在 catSave 函数的 else 语句中。 Maybe you want to do this?也许你想这样做?

const catSave = () => {
        if(catData.length > 0){
            if(catsSelected.length < 1){
                setCatsSelected(catData)
            }
            else{
                setCatsSelected([...catsSelected, catData[0]])
            }
        }
        setModalVisible(!modalVisible)
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM