-
카테고리
-
세부 분야
풀스택
-
해결 여부
해결됨
메시지 검색기능에서 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);
답변을 작성해보세요.
0
John Ahn
지식공유자2021.01.25
안녕하세요
현재 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가 안들어가있는 이유를 찾아야합니다 ~ !
답변 1