Почему после запуска модального окна, ref возвращает null-овые объекты?

Всем привет!

Помогите пожалуйста, второй день сижу и не могу выяснить.
Прилагаю ссылку на песочницу.

Суть проблемы: есть React приложение со следующей структурой:

--App
-----Mw (тело модального окна react-bootstrap)
-----MainCheckbox (главный чекбокс, который переключает все другие чекбоксы)
-----CheckboxContainer (рендерит подконтрольные MainCheckbox чекбоксы)

До того, пока в App не было компонента модального окна (Mw), чекбоксы работали замечательно. Вставил компонент Mw, модальное окно работает, но после открытия/закрытия модального окна, при клике на главный чекбокс, приложение падает. Путем дебаггинга выяснил, что callback ref (на основе которого работает переключатель чекбоксов), после открытия/закрытия модального окна возвращает не только все три чекбокса, но и три null-a. Такое чувство, как-будто он где-то сохранил элементы чекбокса, а после ре-рендера, вместе с актуальными чекбоксами, возвращает сохраненные чекбоксы, но так как их нет, то возвращает null. Ссылку для наглядности приложил выше.

Заранее благодарю за любую помощь.
  • Вопрос задан
  • 110 просмотров
Решения вопроса 1
@kazsat Автор вопроса
Разобрался, спасибо LEXA_JA что тыкнули на документацию, почему-то этот момент пропустил. В общем, ref надо было определить не как встроенную функцию, а определить функцию как член класса и использовать его. Ссылка
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@LEXA_JA
Начнем с того, почему так происходит. ref срабатывает каждый раз, когда происходит рендер. Поскольку модалка использует setState, которая вызывает render, который запускает функцию в ref, в массив каждый раз попадает все больше ссылок, с каждым открытием\закрытием модалки. Иногда в ref может быть null, из-за инлайн функции Подробнее.
Однако такой подход в принципе не правильный.
Для управлением состоянием чекбокса, использование ref не принято. Использование ref в React в принципе нежно использовать не очень часто. Правильный подход - использование props: checked\defaultChecked и onChange Формы
Вообще, состояние должно быть в реакте, а реакт сам применяет его на DOM, в это его суть.

Правильный вариант - положить состояние чекбоксов в стейт, в виде массива или Set'а.
state = {
		values: [false, false, false], // Изначально все 3 чекбокса выключены
	};

	onToggleCheckbox = (checked, index) => {
		this.setState(({ values: prevValues }) => {
			const newValues = [...prevValues]; // меняем состояние нужного чекбокса по индексу
			newValues[index] = checked;

			return {
				value: newValues,
			};
		});
	};

	onToggleAll = checked => {
		this.setState(({ values }) => ({
			values: values.map(() => checked),
		}));
	};

Тогда отрисовка чекбоксов:
<div>
    {this.props.checked.map((value, index) => (
      <input
        type="checkbox"
        checked={value}
        key={index}
        onChange={event => this.props.onToggle(event, index)}
      />
    ))}
  </div>


Состояние чекбокса который переключает все остальный вычислимое:
<input type="checkbox" checked={this.props.values.every(value => value)} onChange={event => this.props.onToggleAll(event.target.checked)} />
Ответ написан
Ваш ответ на вопрос

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

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