React: Управление DOM в componentDidUpdate

Созданный на 23 сент. 2016  ·  3Комментарии  ·  Источник: facebook/react

Привет, это больше похоже на вопрос, я хотел бы начать обсуждение манипуляции с DOM в componentDidUpdate .

Я создаю плагин React. Он должен выполнить некоторые вычисления DOM, потому что CSS недостаточно мощный, чтобы покрыть все, что нужно этому плагину. Проблема в том, что мне нужно настроить некоторые свойства CSS в зависимости от возвращаемого значения getBoundingClientRect () какого-либо другого элемента DOM, отображаемого тем же компонентом .

Итак, технически у нас есть 3 варианта:

1) Вычислить getBoundingClientRect в componentDidUpdate и вызвать setState с вычисленными значениями. Я боюсь бесконечного цикла, который может произойти в определенных случаях, поэтому я бы не пошел на этот.

2) Сделайте как в 1) и немного поиграйте с shouldComponentUpdate , но это кажется очень сложным и нечитаемым. Появляется множество вопросов, которые зависят от конкретного варианта использования.

3) Обновите DOM из componentDidUpdate. Это решение, которое я решил использовать, оно работает, оно простое, стабильное и работает по назначению. Однако я чувствую, что нахожусь на грани, поэтому я хотел дважды проверить, что это нормальный способ делать что-то. Можно ли манипулировать DOM в componentDidUpdate ? Он вызывается каждый раз, когда завершается render , и я готов выбросить свои изменения, потому что в следующем render я снова изменю DOM.

Вот часть кода

componentDidMount() {
  this.recalculateIndent();
}

componentDidUpdate() {
  this.recalculateIndent();
}

recalculateIndent() {
  // calculate indent based on getBoundingClientRect of some DOM reference
  this.textareaRef.style.textIndent = `${indent}px`;
}

render() {
   return (
   ...
   <textarea ref={ref => this.textareaRef = ref}/>
   ...
   );
}

Самый полезный комментарий

@jvorcak с использованием componentDidUpdate - это правильное место для управления DOM вручную после рендеринга. Согласно документам:

Используйте это как возможность работать с DOM, когда компонент был обновлен.

Кроме того, мы стараемся использовать средство отслеживания проблем исключительно для запросов функций и отчетов об ошибках. Вопросы по использованию следует направлять в другое место, например в обсудить.reactjs.org или StackOverflow. Спасибо!

Все 3 Комментарий

Каждое решение (метод жизненного цикла компонента) подходит для конкретной ситуации, но манипуляции с DOM неверны. Используйте состояние и повторно визуализируйте компонент. Пример моего последнего варианта использования «фиксированный заголовок для таблицы + виртуальная прокрутка для тела таблицы», я надеюсь, что это поможет вам понять правильный поток.

  1. Конструктор компонента: значение начального состояния: bodyHeight = 0 (или null, как хотите).
  2. Сначала отображается заголовок таблицы, но пустое тело таблицы (0 строк).
  3. componentDidMount - чтение заголовка и высоты DOM контейнера (+ некоторые вычисления ...) и setState для bodyHeight (повторный рендеринг).
  4. Второй рендер, bodyHeight! == 0, будет отрисован тело таблицы. Теперь известен параметр высоты ( я могу установить его, используя опору компонента "style", а не манипуляции с DOM ), я могу добавлять компоненты для строк.
  5. Дополнительный прослушиватель событий для «изменения размера» (изменение размера документа / браузера), добавьте в componentDidMount, удалите в componentWillUnmount. В обработчике событий я делаю то же самое, что и в componentDidMount - читаю новые значения высоты DOM и setState.
  6. Нет никаких манипуляций с DOM вручную, response выполняет свою работу.

@jvorcak с использованием componentDidUpdate - это правильное место для управления DOM вручную после рендеринга. Согласно документам:

Используйте это как возможность работать с DOM, когда компонент был обновлен.

Кроме того, мы стараемся использовать средство отслеживания проблем исключительно для запросов функций и отчетов об ошибках. Вопросы по использованию следует направлять в другое место, например в обсудить.reactjs.org или StackOverflow. Спасибо!

Что делать, если вы хотите обновить один компонент после изменения чего-то в другом?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги