Элемент в массиве удален, но пользовательский интерфейс не обновляется в React Native

Это приложение разработано компанией react-native. Я знаю, что этот вопрос можно продублировать, но я попробовал все решения, и они не сработали.

Я очень запуталась. Когда какой-либо элемент добавляет / выталкивает массив в объект, элемент пользовательского интерфейса обновляется. Но когда я удаляю / соединяю один и тот же массив, этот механизм не работает, и элемент пользовательского интерфейса не обновляется. Почему?

function createWordsetObject() {
  const object = {
    name: '',
    words: [],
  }

  return object
}

export default function AddWordScreen({ navigation, route }) {
  const [wordsetObject, setWordsetObj] = useState(
    route.params == null ? createWordsetObject() : route.params.wordSetObject
  )
  const [wordsetName, setWordsetName] = useState(
    route.params == null ? '' : route.params.wordSetObject.name
  )
  const [word, setWord] = useState('')
  const [meaning, setMeaning] = useState('')

  const onPressAddButtonHandler = () => {
    if (word != null && meaning != null) {
      var addRecord = { word: word, meaning: meaning }
      wordsetObject.words.push(addRecord)
      setWord('')
      setMeaning('')
      printLog()
    }
  }
  const onPressDeleteWordButton = index => {
    var modifiedObj = wordsetObject
    if (modifiedObj.words.length > 0) {
      console.log(modifiedObj.words.length)
      modifiedObj.words.splice(index, 1)
    }
    setWordsetObj(modifiedObj)
    console.log(wordsetObject.words.length)
  }

  return (
    <ScrollView>
      {wordsetObject.words.map((item, index) => {
        return (
          <ListItem
            key={index}
            title={item.word}
            subtitle={item.meaning}
            bottomDivider
            rightIcon={
              <View style={{ flexDirection: 'row' }}>
                <MCIcon name="pencil" size={22} />
                <MCIcon
                  name="delete"
                  size={22}
                  color="red"
                  onPress={() => onPressDeleteWordButton(index)}
                />
              </View>
            }
          />
        )
      })}
    </ScrollView>
  )
}


person forever_software    schedule 04.06.2020    source источник


Ответы (1)


Я бы создал новый объект вместо того, чтобы манипулировать существующим.

const onPressDeleteWordButton = (index) => {

        if(wordsetObject.words.length) {
          setWordsetObj(modifiedObj => {
            return {
              ...modifiedObj,
              words: modifiedObj.words.filter((pr, ind) => ind !== index)
            }
          });
        }
    }
person Józef Podlecki    schedule 04.06.2020
comment
Это работает. Спасибо за быстрый ответ, но почему не сработала манипуляция способом? - person forever_software; 04.06.2020
comment
@forever_software При использовании splice метод, он изменяет массив, но когда вы _ 2_ / spread operator / Object.assign, они создают новый массив / объект. Новое - это ключевой момент. Поскольку React выполняет неглубокое сравнение для обнаружения изменений для повторного рендеринга пользовательского интерфейса. Когда вы изменяете существующий объект / массив JS, React видит, что этот объект все еще имеет ту же старую ссылку, поэтому он не выполняет повторную визуализацию. - person Ajeet Shah; 04.06.2020