#javascript #reactjs
#javascript #reactjs
Вопрос:
У меня есть приложение, и мне нужно вести историю поиска, на мой взгляд Map
, здесь подходит:
const [searchHistory, setSearchHistory] = useState(new Map());
чтобы обновить его, используйте setSearchHistory(new Map([[text, result.repos]]));
, но он заменяет карту новой картой, не могли бы вы сказать мне, как я могу добавить значение к карте, инициализированной в состоянии?
Ответ №1:
Функция обновления состояния, возвращаемая, useState
не объединяет состояние, как this.setState()
в компонентах на основе классов. В функциональных компонентах вы должны вручную объединить старое состояние с новым состоянием.
Вы передаете новый Map
объект setSearchHistory
, поэтому он полностью перезапишет старое состояние.
Вы можете обновить состояние, сначала скопировав записи в старом Map
объекте в новый Map
объект, а затем добавьте новую запись, которую вы хотите добавить в состояние. Наконец, передайте этот новый Map
объект setSearchHistory
.
// copy (shallow) the old map's entries in the new Map
const updatedMap = new Map(searchHistory);
// add the new entry in the 'updatedMap'
updatedMap.set(key, value);
// update the state
setSearchHistory(updatedMap);
Комментарии:
1. Спасибо! У меня вопрос, могу ли я написать что-то вроде этого setSearchHistory(новая карта (searchHistory).set(ключ, значение)) ?
2. Да, этот код выполняет точно то же самое, что и код в ответе.
Ответ №2:
Вы можете добиться этого следующим образом:
const [searchHistory, setSearchHistory] = useState(new Map());
function onChange(key, value) {
// change the searchHistory map with a new Map from the current searchHistory, and the new key, value
setSearchHistory(new Map([...searchHistory, [key, value]]));
}
Комментарии:
1. Вы никогда не должны изменять переменные состояния напрямую. React сообщает вам принять состояние как неизменяемую переменную и обновлять его только с помощью функций set … .
2. Извините, я виноват. Проверьте это сейчас, пожалуйста.
3. У меня это не сработало, но это сработало — я создал новую карту с помощью (key, value)
newMap.set(key, value)
. а затем соединил обе карты следующим образомnew Map(...oldMap, ...newMap)
4. Почему это не сработало для вашего случая?
5. Я задал вопрос, чтобы найти способ не создавать новую карту полностью, скопировав все значения, но, похоже, это неизбежно при использовании react state. Для меня это решение выглядит более элегантно, чем принятый ответ, поэтому я присуждаю награду.