ReactJS, как получить nextState, приходит в this.state прошлое значение state(полностью готовый пример)?

Откройте консоль введите в два поля значение, когда они больше или равны 8, меняем класс кнопки, но когда происходит проверка на длину, и мы уберем один символ, в state у нас по факту 7 но при получении длины у нас 8 и состояние кнопки остается активное, через setTimeout работает но это костыль.
Спасибо за помощь, готовый компонент тут => stackblitz.com/edit/template?file=components%2FForm.js
Откройте консоль, можно увидеть длину поля логин.

Дело в том что setState - асинсхронная операция, и когда ты вызываешь getStateValues сразу после setState, то .state внутри getStateValues показывает еще не обновившееся значение.

Что можно сделать дешево, но с потенциальными проблемами в будущем: отказаться от использования this.state внутри getStateValues. Вместо этого в getStateValues делать как setState текущему компоненту, так и делать setState родительскому.

Если ситуация позволяет лучше возьми решение для state management. Такое как redux или mobx. Тогда оба компонента (и инпут и кнопка) будут смотреть на значение из state management решения.

Не вышло, тебе не сложно подправить в моем решении. Пожалуйста. Посмотрю где протупил. Спасибо большое.

Не ожидай что я в будущем буду писать код за тебя. Только в качестве исключения https://template-htkamg.stackblitz.io

Я полнотью избавился от getStateValues, а действия которые выполняла эта функция, перенес в handleChange.

Мне не нравится это решение, и его надо будет переделывать чтобы оно поддерживало поведение для clearAllVules. Наверное менее мерзкий вариант будет если ты все обновления состояния будешь пропускать через одну и ту же функцию, которая будет вызывать stateButton.

Спасибо большое, но код не смог посмотреть))

Так открывается у тебя?

Так да, спасибо огромное, изучу детально, Надеюсь когда то буду писать хороший код, очень много прилагаю к этом усилий. Пока это полный треш((

Подскажите пожалуйста, как работать с вложенным state ??

state = {
   form: {
      login: '',
      password: ''
   }
}

Когда пишу вот так получаю ошибку, this.setState({[form.login]: ‘1234’}).

this.setState({
	form: {
		login: 'kokoko'
	}
})
1 лайк

Спасибо, вот еще нашел https://vanslaars.io/post/setstate-lenses/
Работаю с Ramda.JS удобно.

Автор предлагает

  1. Дополнительную абстракцию (lenses)
  2. Думать терминами композиций функций. Ничего не имею против, но для задачи, стоящей перед тобой (изменение вложенных свойств), это оверхед.
  3. Не предлагает решения как изменять сложные вложенные объекты (несколько вложенных свойств. Одно - длина логина-пароля, второе - результат валидации).

Я бы делал clone потом deep-merge this.state и не парился бы с рамбдой. Реализаций обоих в интернете достаточно. Такой подход кажется проще тем что думать можно меньше. Все что происходит с объектом происходит в трех строчках и не размазано в абстракциях по файлу.

this.setState(deepMerge(clone(this.state), {
	form: {
		login: 'kokoko'
	}
}))

Спасибо, а функции ‘deepMerge’ , ‘clone’ это с какой библиотеки?

Не из какой конкретной. Я использовал имена чтобы описать действия функций. Легкое гугление дает пригоршню результатов: https://www.npmjs.com/package/deepmerge

Вот этот выглядит неплохо. И имеет встроенную настройку которая делает clone объектов. Так что можно обойтись одной функцией. Но все же убедись что она работает как ожидается (и клонирует и мержит объекты).

Понял, да у меня так вышло, что изменил в поле form: login: ‘test’, осталось у меня в поле form только login, поле password в нем нет((

Значит мой пример нерабочий. Пример с deepmerge будет работать

К сожалению, код с вопросом не доступен (уже не тот :) ). Но по твоему ответу видно где у человека была проблема. Возможно я не прав или не правильно понимаю вопрос. Но решить проблему асинхронности можно, просто передав callback как второй параметер в setState.

this.setState({value: 'new value'}, getStateValues)
1 лайк

Так сработает. Проще и красивее. Спасибо