#reactjs #use-state
Вопрос:
У меня есть этот небольшой преобразователь видимости, и он безупречно работает для изменения атрибута переменной видимости, но моя проблема в том, что он удаляет все остальные переменные из «productsState». Он не должен сохранять другие переменные?
const listing = () => {
const visibility= !productsState.visibility;
setProdState({visibility : visibility})
}
Ответ №1:
Примечание
В отличие от
setState
метода, найденного в компонентах класса,useState
не выполняет автоматическое объединение объектов обновления. Вы можете повторить это поведение, объединив форму средства обновления функций с синтаксисом распространения объектов:setState(prevState => { // Object.assign would also work return {...prevState, ...updatedValues}; });
Ваш код должен быть обновлен, чтобы использовать обновление функционального состояния и распространяться в предыдущем состоянии:
const listing = () => {
setProdState(prevState => ({
...prevState,
visibility: !prevState.visibility,
}))
}
Другие ответы здесь, которые выполняют одно из следующих действий, неправильно обновляются по сравнению с предыдущим состоянием (хотя может не быть никаких явных или неблагоприятных побочных эффектов).:
const visibility= !productsState.visibility;
это переключение из состояния текущего рендеринга, а не из предыдущего состояния.- Некоторым вариантом
setProdState({...productsState, visibility : visibility})
as сноваproductsState
является состояние из цикла рендеринга, в котором ставится в очередь обновление, а не предыдущее состояние.
Ответ №2:
Вы можете использовать операторы распространения здесь
const listing = () => {
const visibility= !productsState.visibility;
setProdState({...productsState, visibility : visibility})
}
Узнайте больше о синтаксисе распространения
Ответ №3:
как productsState
и объект, вы можете распространять его при передаче setProdState
или использовать Object.assign
, что имеет тот же эффект
setProdState({...productsState, visibility: visibility});
или
setProductState(Object.assign({}, productsState, {visibility: visibility}));