我有一个模式,用户可以从中选择类别,然后将该类别加载到他们个人资料页面上的平面列表中.选择第一个类别后,它会正确加载所需的格式:

enter image description here

当用户从模式中选择并添加第二项时,这些项将消失,如下所示:

enter image description here

And when a third item is added, this error is prompted: enter image description here

CODE:

用户从中选择的类别数组,以及钩子状态:

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

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

用户选择所需类别后调用的函数:

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).

用户确认所选类别后调用的函数:

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

以及所选类别加载到的平面列表:

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

以下是修改时选择的CATS的控制台日志(log),以供参考:

[] // 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.

我需要的是平面列表不可见,并且在添加第三项后不提示此错误,有人确定为什么会发生这种情况吗?

谢谢你的帮助.

推荐答案

Issue

  1. 你正在变异状态
  2. Array.prototype.push的结果保存到状态,即新的数组长度,而不是更新的数组
  3. 在随后的渲染中,当catsSelected不再是一个数组,而是一个数字时,push方法不存在

Array.prototype.push

100方法将一个或多个元素添加到

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

使用功能状态更新将前一个stat的数组中的更新正确排队.浅层复制前一个状态的数组并附加新数据.

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

Javascript相关问答推荐

使用 Frida 重载函数时从列表中删除元素

过滤递归数组

如何使用 Jquery 访问 JSON 的“对象”部分?

在提交表单之前询问用户

使用 HTML、CSS 和 JavaScript 在页面刷新时保持选定的主题

需要目录而不是 js 文件

根据光标位置调整 jQuery 自动完成 UI 的大小

为什么我的 Select 的 MenuProps 中的 PaperProps 中的样式不适用于选择

画布 putimagedata 有时不会像预期的那样绘制

Sequelize ORDER BY ASC 数字字符串

深入研究 Rx.ReplaySubject:如何延迟 `next()`?

从具有相同 id 的元素列表中动态获取特定元素的值

使用 JavaScript/React 过滤 API 响应

有没有办法重新加载页面,然后立即打开一个模式?

我该如何解决这个错误:FirebaseError: Expected type 'mc', but it was: a custom yc object?

React - 从子组件更新状态,然后根据状态做一些事情

.push( ) 没有更新变量

异步脚本何时触发 onload?

KnockoutJS - 如何使用可观察数组隐藏 foreach 中的某些元素?

如何让这个 flex 容器包装在 React 中?