Реагировать на исчезновение элементов Native FlatList

У меня есть Modal, из которого пользователь выбирает категории, а затем эта категория загружается в FlatList на странице их профиля. Когда выбрана первая категория, она правильно загружается с желаемым форматированием:

Реагировать на исчезновение элементов Native FlatList

Когда пользователь выбирает и добавляет второй элемент из модального окна, элементы исчезают, например:

Реагировать на исчезновение элементов Native FlatList

И когда добавляется третий элемент, появляется эта ошибка: Реагировать на исчезновение элементов Native FlatList

КОД:

Массив категорий, из которого выбирает пользователь, и состояния хука:

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, в который загружаются выбранные категории:

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

Для справки, вот консольный лог 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.

Мне нужно, чтобы FlatList не был невидимым, и чтобы эта ошибка не выдавала запрос после добавления третьего элемента, кто-нибудь уверен, почему это происходит?

Спасибо за помощь.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
22
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, ваша проблема связана с оператором else в функции catSave. Может быть, вы хотите сделать это?

const catSave = () => {
        if (catData.length > 0){
            if (catsSelected.length < 1){
                setCatsSelected(catData)
            }
            else{
                setCatsSelected([...catsSelected, catData[0]])
            }
        }
        setModalVisible(!modalVisible)
    }
Ответ принят как подходящий

Проблема

  1. Вы мутируете состояние
  2. Вы сохраняете результат Array.prototype.push в состояние, которое представляет собой новую длину массива, а не обновленный массив.
  3. При последующем рендеринге, когда catsSelected больше не массив, а число, метод push не существует.

См. Array.prototype.push

The push() method adds one or more elements to the end of an array and returns the new length of the array.

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);
}

Решение

Используйте обновление функционального состояния, чтобы правильно поставить в очередь обновление из массива предыдущей статистики. Неглубоко скопируйте массив предыдущего состояния и добавьте новые данные.

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

Пропущен тот факт, что .push() возвращает новую длину массива, спасибо за ответ, теперь отлично работает.

guyman 14.05.2022 21:58

Другие вопросы по теме