1편에서 간단히 구현한 로직들을 컴포넌트로 분리 후, css를 적용했습니다.
사용자의 닉네임은 입력받은 후 , Recoil로 상태관리를 진행했습니다.
//state.ts
import { atom } from "recoil";
export const nameState = atom({
key: "nameState",
default: "",
});
// index.tsx
const [userName, setUserName] = useRecoilState(nameState);
.
.
.
return (
<div className={styles.main}>
{userName === "" ? (
//닉네임 입력화면
<NickNameInput userNameEnterKeyDown={userNameEnterKeyDown} />
) : (
//채팅화면
<ChatTemplate
chatMessage={chatMessage}
scrollRef={scrollRef}
message={message}
setMessage={setMessage}
messageEnterKeyDown={messageEnterKeyDown}
userName={userName}
/>
)}
</div>
);
채팅내역이 많아진 경우, 사용자가 채팅을 입력하면 최하단으로 스크롤하는 기능을 추가했습니다.
해당 기능은 useRef와 scrollIntoView 메서드를 활용하여 구현가능합니다.
const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => {
scrollRef.current?.scrollIntoView({
behavior: "smooth",
block: "end",
inline: "nearest",
});
}, [chatMessage]);
.
.
.
.
<div className={styles.chatMessageBox}>
{chatMessage.map((item, index) => {
return (
<div key={index} className={item.userName === userName ? styles.myMessage : styles.otherMessage}>
<span>{item.userName}</span>
<p>{item.message}</p>
</div>
);
})}
<div ref={scrollRef} />
</div>
- 채팅 최하단 div태그에 scrollRef를 등록해줍니다.
- chatMessage(채팅 메세지 배열)이 변경될 경우 , scrollIntoView이벤트를 통해 scrollRef위치로 이동시켜줍니다.
전체소스코드는 아래의 저장소에서 확인 가능합니다.
깃허브 저장소 이동