Реализуйте UseEffect React для прослушивания только приращения/уменьшения

avatar
Tal Kohavy
8 августа 2021 в 21:57
61
1
2

Я создал приложение для чата и использую useEffect для прослушивания messages.length, чтобы прокрутить вниз при получении нового сообщения - increment в messages.length.
Однако есть также случай, когда я удаляю сообщение decrement в messages.length. Это означает, что при удалении я тоже прокручиваюсь вниз, и я хотел бы избежать такого поведения. Сообщения хранятся в моем хранилище избыточности и доступны как реквизит.

Есть ли способ для useEffect прослушивать только приращение?
Есть ли способ получить доступ к предыдущему состоянию сообщений?
Или сохранение переменной prevLength неизбежно?

Вот часть моего кода, которую нужно пересмотреть:

// Scroll to bottom upon new message:
useEffect(() => {
    scrollDown();
}, [messages.length]);

Вот весь код:

import { useState, useEffect} from 'react';
//Components:
import ChatBubble from './ChatBubble';
import ScrollButton from './ScrollButton';

export default function MessagesBoard({ messages }) {

  //useState:
  const [showScrollButton, setShowScrollButton] = useState(false);

  //Event: Scroll to bottom upon new message
  useEffect(() => {
    scrollDown();
  }, [messages.length]);

  const scrollDown = () => {
    ....
  };

  return (
    <div className='chatMessagesBlock'>
      <div className='messagesCanvas'>
        {messages.map((chatMessage) => {
          return (
            <ChatBubble
              key={msgID}
              msgID={msgID}
              sender={sender}
              msgContent={msgContent}
            />
          );
        })}
      </div>

      <ScrollButton
        showScrollButton={showScrollButton}
        scrollDown={scrollDown}
      />
    </div>
  );
}
Источник

Ответы (1)

avatar
Kelvin Schoofs
8 августа 2021 в 21:59
2

Вы можете отслеживать предыдущую длину в useRef:

const prevLength = useRef(0);
useEffect(() => {
    if (prevLength.current < message.length) {
        scrollDown();
    }
    prevLength.current = messages.length;
}, [messages.length]);