Я хочу создать систему чата и автоматически прокручивать вниз при входе в окно и при поступлении новых сообщений. Как вы автоматически прокручиваете до конца контейнера в React?
128
Как упоминал Тушар, вы можете оставить фиктивный div внизу чата:
render () {
return (
<div>
<div className="MessageContainer" >
<div className="MessagesList">
{this.renderMessages()}
</div>
<div style={{ float:"left", clear: "both" }}
ref={(el) => { this.messagesEnd = el; }}>
</div>
</div>
</div>
);
}
а затем прокрутите до него всякий раз, когда ваш компонент обновляется (т.е. состояние обновляется по мере добавления новых сообщений):
scrollToBottom = () => {
this.messagesEnd.scrollIntoView({ behavior: "smooth" });
}
componentDidMount() {
this.scrollToBottom();
}
componentDidUpdate() {
this.scrollToBottom();
}
Здесь я использую стандартный метод Element.scrollIntoView .
this.messagesEnd.scrollIntoView()
у меня работал нормально. В использовании не было необходимостиfindDOMNode()
.scrollToBottom(){this.scrollBottom.scrollIntoView({ behavior: 'smooth' })}
она работала в более новых версияхЯ просто хочу обновить ответ, чтобы он соответствовал новому
React.createRef()
методу , но в основном он такой же, просто помните оcurrent
свойстве в созданной ссылке:ОБНОВИТЬ:
Теперь, когда крючки доступны, я обновляю ответ , чтобы добавить использование
useRef
иuseEffect
крючков, реальная вещь делает магию (React рефов иscrollIntoView
метод DOM) остается тем же:Также сделал (очень простой) codeandbox, если вы хотите проверить поведение https://codesandbox.io/s/scrolltobottomexample-f90lz
источник
this.messagesEnd.current
всегда есть. Тем не менее важно заметить, что вызовthis.messagesEnd.current
перед первым рендерингом приведет к указанной вами ошибке. Thnx.this.messagesEnd
в вашем первом примере в методе scrollTo?useEffect
Потребность метод , который будет размещен с() => {scrollToBottom()}
. В любом случае большое спасибоНе используй
findDOMNode
Компоненты класса с ref
Функциональные компоненты с крючками:
источник
behavior
(нельзя редактировать, потому что «редактирование должно содержать не менее 6 символов», вздох).scrollIntoView
withsmooth
на данный момент очень слабая.Спасибо @enlitement
мы должны избегать использования
findDOMNode
, мы можем использоватьrefs
для отслеживания компонентовссылка:
источник
Ты можешь использовать
ref
s, чтобы отслеживать компоненты.Если вы знаете, как установить
ref
один отдельный компонент (последний), пожалуйста, опубликуйте!Вот что я обнаружил:
источник
response-scrollable-feed автоматически прокручивается до последнего элемента, если пользователь уже находился внизу прокручиваемого раздела. В противном случае он оставит пользователя на том же месте. Думаю, это очень полезно для компонентов чата :)
Я думаю, что другие ответы здесь заставят прокрутку каждый раз, независимо от того, где была полоса прокрутки. Другая проблема
scrollIntoView
заключается в том, что он будет прокручивать всю страницу, если ваш прокручиваемый div не был в поле зрения.Его можно использовать так:
Просто убедитесь, что у вас есть компонент-оболочка с определенным
height
илиmax-height
Отказ от ответственности: я являюсь владельцем пакета
источник
Ссылка на свой контейнер сообщений.
Найдите свой контейнер сообщений и сделайте его
scrollTop
атрибут равнымscrollHeight
:Вызов метода выше на
componentDidMount
иcomponentDidUpdate
.Вот как я использую это в своем коде:
источник
Я создал пустой элемент в конце сообщений и перешел к нему. Нет необходимости отслеживать реф.
источник
Если вы хотите сделать это с помощью React Hooks, можно воспользоваться этим методом. В нижней части чата размещен фиктивный div. Здесь используется useRef Hook.
Справочник по API хуков: https://reactjs.org/docs/hooks-reference.html#useref
источник
Я бы порекомендовал самый простой и лучший способ.
Моя версия ReactJS: 16.12.0
Структура HTML внутри
render()
функцииscrollToBottom()
функция, которая получит ссылку на элемент. и прокрутите в соответствии сscrollIntoView()
функцией.и вызовите указанную выше функцию внутри
componentDidMount()
иcomponentDidUpdate()
для получения дополнительной информации
Element.scrollIntoView()
посетите developer.mozilla.orgисточник
Мне не удалось получить ни один из следующих ответов, но простой js помог мне:
источник
Рабочий пример:
Вы можете использовать
scrollIntoView
метод DOM, чтобы сделать компонент видимым в представлении.Для этого при рендеринге компонента просто укажите ссылочный идентификатор для элемента DOM с помощью
ref
атрибута. Затем с помощью методаscrollIntoView
наcomponentDidMount
жизненном цикле. Я просто помещаю рабочий образец кода для этого решения. Ниже приведен компонент, отображающий каждый раз получение сообщения. Вы должны написать код / методы для рендеринга этого компонента.Вот
this.props.message.MessageId
уникальный идентификатор конкретного сообщения чата, переданного какprops
источник
источник
Мне нравится делать это следующим образом.
источник
спасибо 'metakermit' за его хороший ответ, но я думаю, что мы можем сделать его немного лучше, для прокрутки вниз мы должны использовать это:
но если вы хотите прокрутить вверх, вы должны использовать это:
и эти коды общие:
источник
В качестве другого варианта стоит рассмотреть компонент React scroll .
источник
С помощью
React.createRef()
источник
Вот как вы могли бы решить эту проблему в TypeScript (используя ссылку на целевой элемент, к которому вы прокручиваете):
Для получения дополнительной информации об использовании ref с React и Typescript вы можете найти отличную статью здесь .
источник
Полная версия (Машинопись):
источник
Property 'scrollIntoView' does not exist on type 'RefObject<unknown>'.
иType 'HTMLDivElement | null' is not assignable to type 'RefObject<unknown>'. Type 'null' is not assignable to type 'RefObject<unknown>'.
так ...