Как запретить компоненту Chatbox изменять представление входящих сообщений Firebase от других людей? - PullRequest
0 голосов
/ 25 октября 2019

Я внедряю это приложение для чата, которое предлагает две основные функции: общий чат, где каждый может общаться в чате и в приватном чате только между двумя людьми. Я использую Reac-маршрутизатор для навигации. Для публичного чата у меня есть компонент ChatBox (который отображает чаты), который прослушивает изменения базы данных Firebase и перерисовывает соответственно, и реагирует на путь маршрутизатора к этому статическому URL. Здесь все хорошо.

Что касается публичного чата, я использую реагирующий маршрутизатор с динамическим URL-адресом / privateChat /: userID, а компонент ChatBox использует хук useEffect, который повторно отображает компонент при каждом изменении URL-адреса. Итак, у меня есть этот список пользователей, которые находятся в сети, и когда я нажимаю на их имя, которое является ссылкой на маршрутизатор реагирования, я перехожу на URL, и компонент ChatBox отображает и отображает чат с этим человеком. Так что в основном этот компонент ChatBox отображает представления чатов для всех приватных чатов, что я и хочу.

Проблема заключается в следующем: компонент ChatBox ТАКЖЕ слушает изменения в базе данных firebase, как и должно быть, так как это живой чат, и когда появляется новое сообщение, он повторно отображает представление. Итак, если я общаюсь с одним пользователем, а другой пользователь отправляет мне сообщение, мой компонент chatview будет показывать новое сообщение И, следовательно, менять «представление» на новое сообщение, чего я не хочу. Я хотел бы остаться в текущем разговоре, и когда приходит новое сообщение от других пользователей, я хотел бы видеть уведомление, например, значок с номером (в зависимости от текстовых сообщений, которые отправляют люди), и только когда я нажимаю нановый разговор это должно привести меня к этому.

// ChatBox component displaying the real time messages
// re-renders for every firebase db change AND for every chatID change (the private chat)
...
const ChatBox = ({ receiverID, chatID }) => {

  const [chats, setChats] = useState([])

  useEffect(() => {
    const chatRef = firebase.database().ref(`userChat/${chatID}`)
    chatRef.on('value', snapshot => {
      const getChats = snapshot.val()
      let ascChats = []
      for (let chat in getChats) {
        if (getChats[chat].message !== '') {
          ascChats.push({
            id: chat,
            message: getChats[chat].message,
            user: getChats[chat].user,
            date: getChats[chat].timestamp
          })
        }
      }
      const chats = ascChats
      setChats(chats)
    })
  }, [chatID])
...

// React Router dynamic url

...
        <Route path="/privateChat/:chatID" component={PrivateChat} />
...

// ChatBox Component call in PrivateChat component

      <ChatBox receiverID={userID} chatID={chatID} />

Код работает должным образом, но он не удовлетворяет моей цели, упомянутой выше, поэтому я считаю, что я использую неправильный подход для рендеринга входящих чатов от разных людей, использующих один и тот же компонент. Если я удаляю chatID из useEffect, приватный ChatBox не обновляется, когда я перехожу к новому приватному чату с другим пользователем, который мне не подходит, а также, если я использую chatRef.once, он не перерисовывается при новом входящемсообщения (от одного и того же человека), которые являются проблемой. Я попытался разделить useEffect () на две части: первая в компоненте PrivateChat, которая проверяет только то, изменился ли chatID, и если он это сделал, то повторно отображает представление с помощью ChatBox, который теперь содержит только логику для сообщения DB в firebase. меняется. Но это вызывает бесконечный цикл, как ожидается в этом случае, и поэтому, если я удаляю useEffect () и перезаписываю его как componentDidMount с классом React, он не запускается.

Я был бы признателенлюбая помощь, которую я мог получить, чтобы достичь своей цели.

...