• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    해결됨

메시지 검색기능에서 match 함수

21.01.25 18:20 작성 조회수 147

0

이전에 메시지 검색기능 구현하는 강의에서는 잘 실행이 됐는데 지금 다시 시도 해보면 오류가 납니다ㅠ  

정규식과 일치하는지 확인하는 match함수에서 문제가 있는거 같은데 어떻게 해결해야 할지 몰라서 질문 올려 봅니다. ㅠㅠ

구글링을 통해서 찾아 봤을 때는 package-lock.json과 node_modules을 지우고 다시 npm을 설치 해보라 해서 시도 해봤는데 해결 되지 않았습니다.

import React, { Component } from "react";
import Message from "./message";
import MessageHeader from "./message_header";
import MessageForm from "./message_form";
import styles from "./main_panel.module.css";
import { connect } from "react-redux";
import firebase from "../../../firebase";
import { setUserPosts } from "../../../redux/actions/chatRoom_action";
import Skeleton from "../../../commons/components/skeleton";
class MainPanel extends Component {
  messageEndRef = React.createRef();
  state = {
    messagesRef: firebase.database().ref("messages"),
    messages: [],
    messageLoading: true,
    searchTerm: "",
    searchResults: [],
    searchLoading: false,
    typingRef: firebase.database().ref("typing"),
    typingUsers: [],
    listenersList: [],
  };
  componentDidMount() {
    const { chatRoom } = this.props;
    if (chatRoom) {
      this.addMessageListener(chatRoom.id);
      this.addTypingListener(chatRoom.id);
    }
  }
  componentDidUpdate() {
    if (this.messageEndRef) {
      this.messageEndRef.scrollIntoView({ behavior: "smooth" });
    }
  }
  componentWillUnmount() {
    this.state.messagesRef.off();
    this.removeListeners(this.state.listenersList);
  }
  removeListeners = listeners => {
    listeners.forEach(listener => {
      listener.ref.child(listener.id).off(listener.event);
    });
  };
  addTypingListener = chatRoomId => {
    let typingUsers = [];
    this.state.typingRef.child(chatRoomId).on("child_added", DataSnapShot => {
      if (DataSnapShot.key !== this.props.user.uid) {
        typingUsers = typingUsers.concat({
          id: DataSnapShot.key,
          name: DataSnapShot.val(),
        });
        this.setState({ typingUsers });
      }
    });
    this.addToListenersList(chatRoomId, this.state.typingRef, "child_added");
    this.state.typingRef.child(chatRoomId).on("child_removed", DataSnapShot => {
      const index = typingUsers.findIndex(user => user.id === DataSnapShot.key);
      if (index !== -1) {
        typingUsers = typingUsers.filter(user => user.id !== DataSnapShot.key);
        this.setState({ typingUsers });
      }
    });
    this.addToListenersList(chatRoomId, this.state.typingRef, "child_removed");
  };
  addToListenersList = (id, ref, event) => {
    //이미 등록된 리스너인가?
    const index = this.state.listenersList.findIndex(listener => {
      return (
        listener.id === id && listener.ref === ref && listener.event === event
      );
    });
    if (index === -1) {
      const newListener = { id, ref, event };
      this.setState({
        listenersList: this.state.listenersList.concat(newListener),
      });
    }
  };
  handleSearchMessages = () => {
    const chatRoomMessages = [...this.state.messages];
    const regex = new RegExp(this.state.searchTerm, "gi");
    const searchResults = chatRoomMessages.reduce((acc, message) => {
      if (
        (message.content && message.content.match(regex)) ||
        message.user.name.match(regex)
      ) {
        acc.push(message);
      }
      return acc;
    }, []);
    this.setState({ searchResults });
    setTimeout(() => this.setState({ searchLoading: false }), 1000);
  };

  handleSearchChange = event => {
    console.log(event.target.value);
    this.setState(
      {
        searchTerm: event.target.value,
        searchLoading: true,
      },
      () => this.handleSearchMessages()
    );
  };

  addMessageListener = chatRoomId => {
    let messagesArray = [];
    this.setState({ messages: [] });
    this.state.messagesRef.child(chatRoomId).on("child_added", DataSnapShot => {
      console.log(DataSnapShot.val());
      messagesArray.push(DataSnapShot.val());
      this.setState({
        messages: messagesArray,
        messageLoading: false,
      });
      this.userPostCount(messagesArray);
    });
  };
  userPostCount = messages => {
    let usersPost = messages.reduce((acc, message) => {
      if (message.user.name in acc) {
        acc[message.user.name].count += 1;
      } else {
        acc[message.user.name] = {
          image: message.user.image,
          count: 1,
        };
      }
      return acc;
    }, {});
    this.props.dispatch(setUserPosts(usersPost));
  };
  renderMessages = messages =>
    messages.length > 0 &&
    messages.map(message => (
      <Message
        key={message.timeStamp}
        message={message}
        user={this.props.user}
      />
    ));
  renderTypingUsers = typingUsers =>
    typingUsers.length > 0 &&
    typingUsers.map(user => {
      return (
        <span key={user.id}>{user.name}님이 채팅을 입력하고 있습니다.</span>
      );
    });
  renderMessageSkeleton = loading =>
    loading && (
      <>
        {[...Array(6)].map((e, idx) => (
          <Skeleton key={idx} />
        ))}
      </>
    );
  render() {
    const {
      messages,
      searchResults,
      searchTerm,
      typingUsers,
      messageLoading,
    } = this.state;
    return (
      <div className={styles.mainPanel}>
        <MessageHeader
          messages={messages}
          handleSearchChange={this.handleSearchChange}
        />

        <div className={styles.messageBox}>
          {this.renderMessageSkeleton(messageLoading)}
          {searchTerm
            ? this.renderMessages(searchResults)
            : this.renderMessages(messages)}
          {this.renderTypingUsers(typingUsers)}
          <div ref={node => (this.messageEndRef = node)} />
        </div>

        <MessageForm />
      </div>
    );
  }
}
const MapStateToProps = state => {
  return {
    user: state.user.currentUser,
    chatRoom: state.chatRoom.currentChatRoom,
  };
};
export default connect(MapStateToProps)(MainPanel);

답변 1

답변을 작성해보세요.

0

안녕하세요 

현재 match가 undefined가 나오는 상황이네요 ~

 handleSearchMessages = () => {
    const chatRoomMessages = [...this.state.messages];
    const regex = new RegExp(this.state.searchTerm, "gi");
    const searchResults = chatRoomMessages.reduce((acc, message) => {
      if (
        (message.content && message.content.match(regex)) ||
        message.user.name.match(regex)
      ) {
        acc.push(message);
      }
      return acc;
    }, []);
    this.setState({ searchResults });
    setTimeout(() => this.setState({ searchLoading: false }), 1000);
  };

여기에 두군데 match가 있는데 

여기서 message.user 값이 없는것 같습니다. 

그래서 console.log('message', message) 해서   

message 안에  message.user.name 값이 있는지 살펴봐 주세요 

그리고 만약에 없다면  그 user가 안들어가있는 이유를 찾아야합니다 ~ !