@dim5on

Как внутри state у объекта установить только одно значение true, а остальные false?

Делаю компонент аккордеона на React.js. Имею такой state:

this.state = {
    collapse : {
        collapse_1 : true,
        collapse_2 : false,
        collapse_3 : false
        .....
    }
}

Нужно написать функцию toggle, которая будет менять в state конкретное значение объекта collapse на true, а остальные на false.

Пример:

Для этой кнопки:

<Button onClick={this.toggle('collapse_2')}></Button>

Должен вернуть такой state:

this.state = {
    collapse : {
        collapse_1 : false,
        collapse_2 : true,
        collapse_3 : false
        .....
    }
}
  • Вопрос задан
  • 364 просмотра
Решения вопроса 2
0xD34F
@0xD34F Куратор тега React
Зачем хранить данные по всем объектам, если true может быть только один? - сделайте одно свойство, которое будет содержать имя активного объекта:

state = {
  active: null,
}

toggle = ({ target: { dataset: { name } } }) => {
  this.setState(({ active }) => ({
    active: active === name ? null : name,
  }));
}

<button onClick={this.toggle} data-name="collapse_1"></button>
<button onClick={this.toggle} data-name="collapse_2"></button>
<button onClick={this.toggle} data-name="collapse_3"></button>


Хранить всё - это для случая, когда одновременно активными могут быть несколько объектов:

toggle = ({ target: { dataset: { name } } }) => {
  this.setState(({ collapse }) => ({
    collaple: {
      ...collapse,
      [name]: !collapse[name],
    },
  }));
}
Ответ написан
Комментировать
@KnightForce
Так как нужно обращаться к предыдущему снимку состояния, то нужно использовать функцию.
this.setState(({ collapse }) => {
    return {
        collapse: {
            ...collapse,
            [name]: !collapse[name]
        }
    }
})


Если обращения к смене состояния частые, то функцию лучше вынести в метод, чтобы обращаться по ссылке, а не создавать каждый раз.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
kasheibess
@kasheibess
веб уже не тот
Можно пробегаться циклом for in по стейту.

Вообще я бы написал так:
this.state = {
    collapse : [
        {
           id: 1,
           collapse : false
         }
    ]
}

По мне это более универсально. И плюс можно в метод клика, например, передавать id конкретного объекта. Плюс по массиву можно пройтись фильтром без проблем.
Ответ написан
Комментировать
tsepen
@tsepen
Frontend developer
this.setState({
{...state.collapse, [name]: !state.collapse.[name]};
})
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы