React: как изменить стейт переданный в функцию

102
16 апреля 2022, 13:50
const switchInputs = (state) => {
  console.log(state.switchInput) // disabled
  this.setState(() => {
    return {
      switchInput: 'enabled'
    }
  });
}

Даёт ошибку:

TypeError: Cannot read property 'setState' of undefined

Функция находится в другом файле, данные стейта до функции доходят

Answer 1

Передайте в функцию значение this из компонента, там у вас другая переменная this, отсюда и ошибка. Ведь this имеет разное значение при каждом вызове функции, а еще значение this зависит от того, каким образом вызвана функция.

const switchInputs = (me, state) => {
  console.log(state.switchInput) // disabled
  me.setState(() => {
    return {
      switchInput: 'enabled'
    }
  });
}

Ну и вызывайте, передавая в первом параметре this компонента. Раньше вы вызывали функцию с одним параметром, а теперь нужно будет вызвать с двумя. Полезная ссылка для изучения: this

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

Отступая от темы передачи this и вызова setState вне компонента, хотелось бы отметить некоторые моменты.

  • Это может показаться очевидным, но нужно декомпозировать и делать небольшие компоненты. То есть разделять большие компоненты на части из нескольких более мелких компонентов;
  • Создавайте мелкие компоненты, старайтесь создавать их не имеющими состояния (так называемые stateless), это считается признаком хорошего тона;
  • Также, чтобы разгрузить компоненты и переместить бизнес-логику - применяют Redux. С его помощью часть логики уходит в редьюсеры и экшны. Редьюсеры обрабатывают действия, вычисляя новое состояние. Новое состояние всего приложения отправляется в единое хранилище. Компоненты получают новое состояние через props;
  • Совместно с Redux можно использовать Redux-Saga - так называемые саги, и объединять бизнес-логику внутри саг, получается очень удобно, таким образом Redux становится более легким (сосредоточить бизнес-логику в сагах);
  • Еще можно выделять функции хелперы, которые используются более чем в одном месте и не меняют состояния. Функции без изменения state можно выносить за пределы компонента и не переживать, что это может вызвать сайд эффект.

Вот так, объединяя простые и сложные подходы в разработке React приложения можно добиться чистого, понятного и не громоздкого кода. Прикрепил ссылки в описании, но всё же вынесу отдельно:

  • Redux
  • Redux-Saga

UPD: Изначально все покажется сложным, но после того, как удастся прикрутить Redux к своему приложения и написать несколько экшенов и редьюсеров, станет намного легче и проще. Рекомендуется начать использовать Redux на начальном этапе разработки проекта. В большой проект, не имея опыта работы с Redux, сложно будет затянуть Redux, это повлечет большие изменения и займет много времени.

READ ALSO
Не отображается элемент с id=trigger

Не отображается элемент с id=trigger

Есть input при нажатии на который должен появится блок и при повторном нажатии скрыться:

110
countDown или таймер JavaScript

countDown или таймер JavaScript

Подскажите, пожалуйста, что не так с этим таймером? Он не останавливается, когда time = 0 Как мне это исправить?

106
Получить несмещенный объект Date из строки

Получить несмещенный объект Date из строки

Я пытаюсь получить объект Date из строки

88
Изменить название кнопки при нажатии

Изменить название кнопки при нажатии

Хочу изменить текст "Показать все" на "Скрыть"Как можно это сделать?

207