Я создал компонент в React, который должен обновлять свой собственный стиль при прокрутке окна для создания эффекта параллакса.
Компонентный render
метод выглядит так:
function() {
let style = { transform: 'translateY(0px)' };
window.addEventListener('scroll', (event) => {
let scrollTop = event.srcElement.body.scrollTop,
itemTranslate = Math.min(0, scrollTop/3 - 60);
style.transform = 'translateY(' + itemTranslate + 'px)');
});
return (
<div style={style}></div>
);
}
Это не работает, потому что React не знает, что компонент был изменен, и поэтому компонент не визуализируется повторно.
Я попытался сохранить значение itemTranslate
в состоянии компонента и вызвать setState
обратный вызов прокрутки. Однако это делает прокрутку непригодной, так как она очень медленная.
Есть предложения, как это сделать?
javascript
reactjs
Алехандро Перес
источник
источник
render
в том же потоке) должны быть связаны только с логикой, относящейся к рендерингу / обновлению фактического DOM в React. Вместо этого, как показано ниже @AustinGreco, вы должны использовать указанные методы жизненного цикла React для создания и удаления привязки событий. Это делает его автономным внутри компонента и гарантирует отсутствие утечек, гарантируя, что привязка события удалена, если / когда компонент, который его использует, размонтирован.Ответы:
Вы должны привязать слушателя к
componentDidMount
, таким образом, он будет создан только один раз. Вы должны иметь возможность сохранять стиль в состоянии, слушатель, вероятно, был причиной проблем с производительностью.Что-то вроде этого:
источник
this.handleScroll = this.handleScroll.bind(this)
свяжет это внутриhandleScroll
с компонентом, а не с окном.event.target.scrollingElement.scrollTop
Вы можете передать функцию
onScroll
событию в элементе React: https://facebook.github.io/react/docs/events.html#ui-eventsДругой похожий ответ: https://stackoverflow.com/a/36207913/1255973
источник
Мое решение для создания отзывчивой панели навигации (позиция: 'относительная' при отсутствии прокрутки и фиксируется при прокрутке, а не вверху страницы)
У меня нет проблем с производительностью.
источник
Чтобы помочь всем, кто заметил проблемы с медленным поведением / производительностью при использовании ответа Austins и хочет получить пример с использованием ссылок, упомянутых в комментариях, вот пример, который я использовал для переключения класса для значка прокрутки вверх / вниз:
В методе рендеринга:
В методе обработчика:
И добавьте / удалите свои обработчики так же, как упоминал Остин:
документы по исх .
источник
this.scrollIcon.className = whatever-you-want
.className
илиclassList
. Кроме того, мне это не понадобилосьwindow.addEventListener()
: я просто использовал ReactonScroll
, и это так же быстро, пока вы не обновляете реквизиты / состояние!Я обнаружил, что не могу успешно добавить прослушиватель событий, если не передаю true следующим образом:
источник
userCapture
: необязательно. Логическое значение, указывающее, должно ли событие выполняться в фазе захвата или в фазе восходящей цепочки. Возможные значения: true - обработчик событий выполняется на этапе захвата. False - по умолчанию. Обработчик событий выполняется в фазеПример использования classNames , перехватчиков React useEffect , useState и styled-jsx :
источник
с крючками
источник
Пример функционального компонента с использованием useEffect:
Примечание : вам необходимо удалить прослушиватель событий, вернув функцию «очистки» в useEffect. Если вы этого не сделаете, каждый раз, когда компонент обновляется, у вас будет дополнительный слушатель прокрутки окна.
источник
Если вас интересует прокручиваемый дочерний компонент, то этот пример может вам помочь: https://codepen.io/JohnReynolds57/pen/NLNOyO?editors=0011
источник
Я решил проблему, используя и изменив переменные CSS. Таким образом, мне не нужно изменять состояние компонента, которое вызывает проблемы с производительностью.
index.css
Navbar.jsx
Navbar.module.css
источник
Моя ставка здесь заключается в использовании функциональных компонентов с новыми крючками для ее решения, но вместо использования,
useEffect
как в предыдущих ответах, я думаю, что правильный вариант будетuseLayoutEffect
по важной причине:Это можно найти в документации React . Если мы используем
useEffect
вместо этого и перезагружаем уже прокрученную страницу, scrolled будет ложным, и наш класс не будет применяться, что приведет к нежелательному поведению.Пример:
Возможным решением проблемы может быть https://codepen.io/dcalderon/pen/mdJzOYq
источник
useLayoutEffect
. Я пытаюсь понять, о чем вы упомянули.useEffect
сравнению сuseLayoutEffect
..Header--scrolled
иногда класс, но 100% раз.Header--scrolledLayout
применяется правильно благодаря useLayoutEffect.Вот еще один пример использования Крючки fontAwesomeIcon и Кендо UI React
[! [Скриншот здесь] [1]] [1]
источник
Обновление для ответа с помощью React Hooks
Это два крючка - один для направления (вверх / вниз / нет) и один для фактического положения.
Используйте так:
Вот крючки:
источник
Чтобы расширить ответ @ Austin, вы должны добавить
this.handleScroll = this.handleScroll.bind(this)
в свой конструктор:Это дает
handleScroll()
доступ к надлежащей области при вызове из прослушивателя событий.Также имейте
.bind(this)
в виду, что вы не можете использовать методыaddEventListener
или,removeEventListener
потому что каждый из них будет возвращать ссылки на разные функции, и событие не будет удалено при отключении компонента.источник