У меня есть приложение, в котором мне нужно динамически установить высоту элемента (скажем, «app-content»). Он берет высоту "хрома" приложения и вычитает его, а затем устанавливает высоту "контента приложения", чтобы он соответствовал 100% в рамках этих ограничений. Это очень просто с ванильными представлениями JS, jQuery или Backbone, но я изо всех сил пытаюсь выяснить, каким будет правильный процесс для этого в React?
Ниже приведен пример компонента. Я хочу иметь возможность установить app-content
высоту 100% окна минус размер ActionBar
и BalanceBar
, но как я узнаю, когда все отрисовано и куда я помещу расчетные вещи в этот класс React?
/** @jsx React.DOM */
var List = require('../list');
var ActionBar = require('../action-bar');
var BalanceBar = require('../balance-bar');
var Sidebar = require('../sidebar');
var AppBase = React.createClass({
render: function () {
return (
<div className="wrapper">
<Sidebar />
<div className="inner-wrapper">
<ActionBar title="Title Here" />
<BalanceBar balance={balance} />
<div className="app-content">
<List items={items} />
</div>
</div>
</div>
);
}
});
module.exports = AppBase;
javascript
reactjs
Оскар Годсон
источник
источник
Ответы:
componentDidMount ()
Этот метод вызывается один раз после визуализации вашего компонента. Так что ваш код будет выглядеть так.
источник
componentDidUpdate
если значения могут измениться после первого рендера.componentDidMount()
не вызывает переход.componentDidMount: () => { setTimeout(addClassFunction())}
, или используйте rAF, ответ ниже этого обеспечивает этот ответ.Один недостаток использования
componentDidUpdate
, илиcomponentDidMount
является то, что они на самом деле выполняются до того, как элементы dom завершены, но после того, как они были переданы из React в DOM браузера.Скажем, например, если вам нужно было установить node.scrollHeight для визуализированного node.scrollTop, то элементов DOM React может быть недостаточно. Вам нужно подождать, пока элементы будут окрашены, чтобы получить их высоту.
Решение:
Используйте,
requestAnimationFrame
чтобы гарантировать, что ваш код запускается после рисования вашего недавно отрендеренного объектаисточник
_this.getDOMNode is not a function
какого черта этот код?По моему опыту, этого
window.requestAnimationFrame
было недостаточно, чтобы убедиться, что DOM был полностью обработанcomponentDidMount
. У меня работает код, который обращается к DOM сразу послеcomponentDidMount
вызова, и использование толькоwindow.requestAnimationFrame
приведет к тому, что элемент будет присутствовать в DOM; однако обновления размеров элемента еще не отражены, поскольку перекомпоновка еще не произошла.Единственный действительно надежный способ для этого - заключить мой метод в a
setTimeout
и a,window.requestAnimationFrame
чтобы гарантировать очистку текущего стека вызовов React перед регистрацией для рендеринга следующего кадра.Если бы мне пришлось размышлять о том, почему это происходит / необходимо, я мог бы увидеть, как React пакетирует обновления DOM и фактически не применяет изменения к DOM до тех пор, пока текущий стек не будет завершен.
В конечном счете, если вы используете измерения DOM в коде, который вы запускаете после обратных вызовов React, вы, вероятно, захотите использовать этот метод.
источник
Просто чтобы немного обновить этот вопрос новыми методами Hook, вы можете просто использовать
useEffect
ловушку:Также, если вы хотите запустить перед раскраской раскраски, используйте
useLayoutEffect
крючок:источник
Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.
.Вы можете изменить состояние и затем выполнить свои вычисления в обратном вызове setState . Согласно документации React, это «гарантированно сработает после применения обновления».
Это должно быть сделано в
componentDidMount
коде или где-то еще (например, в обработчике событий изменения размера), а не в конструкторе.Это хорошая альтернатива,
window.requestAnimationFrame
и у нее нет проблем, о которых упоминали некоторые пользователи (необходимость комбинировать ееsetTimeout
или вызывать несколько раз). Например:источник
Я чувствую, что это решение грязное, но здесь мы идем:
Теперь я просто сижу здесь и жду поданных голосов.
источник
У React есть несколько методов жизненного цикла, которые помогают в этих ситуациях, списки, включая, но не ограничиваясь, getInitialState, getDefaultProps, componentWillMount, componentDidMount и т. Д.
В вашем случае и в случаях, когда необходимо взаимодействовать с элементами DOM, вам нужно подождать, пока dom не будет готов, поэтому используйте componentDidMount, как показано ниже:
Также для получения дополнительной информации о жизненном цикле реакции вы можете посмотреть следующую ссылку: https://facebook.github.io/react/docs/state-and-lifecycle.html.
источник
Я столкнулся с той же проблемой.
В большинстве сценариев используется взлом
setTimeout(() => { }, 0)
вcomponentDidMount()
работало.Но не в особом случае; и я не хотел использовать,
ReachDOM findDOMNode
так как документация говорит:(Источник: findDOMNode )
Таким образом, в этом конкретном компоненте мне пришлось использовать
componentDidUpdate()
событие, поэтому мой код оказался таким:А потом:
Наконец, в моем случае мне пришлось удалить слушателя, созданного в
componentDidMount
:источник
После рендеринга вы можете указать высоту, как показано ниже, и указать высоту для соответствующих компонентов реакции.
или вы можете указать высоту каждого реагирующего компонента, используя sass. Укажите первые 2 основных компонента div реагирования с фиксированной шириной, а затем высоту основного div третьего компонента с помощью auto. Таким образом, на основе содержимого третьего div будет назначена высота.
источник
На самом деле у меня проблемы с похожим поведением, я рендерил элемент видео в компоненте с его атрибутом id, поэтому, когда RenderDOM.render () завершает работу, он загружает плагин, которому нужен идентификатор, чтобы найти заполнитель, и он не может его найти.
SetTimeout с 0 мс внутри componentDidMount () исправил это :)
источник
Из документации ReactDOM.render () :
источник
ReactDOM.render
, а не для уровня компонентаReactElement.render
(который здесь обсуждается).Для меня нет комбинации
window.requestAnimationFrame
илиsetTimeout
выдающиеся результаты не дали. Иногда это срабатывало, но не всегда, а иногда было бы слишком поздно.Я исправил это, повторяя
window.requestAnimationFrame
столько раз, сколько необходимо.(Обычно 0 или 2-3 раза)
Ключ
diff > 0
: здесь мы можем точно знать, когда страница обновляется.источник
У меня была странная ситуация, когда мне нужно напечатать реагирующий компонент, который получает большой объем данных и рисует на холсте. Я перепробовал все упомянутые подходы, ни один из них не работал надежно для меня, с requestAnimationFrame внутри setTimeout я получаю пустой холст в 20% случаев, поэтому я сделал следующее:
По сути, я создал цепочку из requestAnimationFrame, не уверен, что это хорошая идея или нет, но пока это работает для меня в 100% случаев (я использую 30 в качестве значения для n-переменной).
источник
На самом деле существует намного более простая и чистая версия, чем использование анимации запроса или тайм-аута. Я удивился, что никто не поднял это: обработчик загрузки vanilla-js. Если вы можете использовать компонент mount, если нет, просто привяжите функцию к обработчику загрузки компонента jsx. Если вы хотите, чтобы функция запускала каждый рендер, также запустите его, прежде чем возвращать результаты в функцию рендеринга. код будет выглядеть так:
}
источник
Немного обновления с
ES6
классами вместоReact.createClass
Также - проверьте методы жизненного цикла компонента React: Жизненный цикл компонента
У каждого компонента есть много методов, подобных
componentDidMount
например.componentWillUnmount()
- компонент собирается удалить из браузера DOMисточник