개발 공부 기록

나는 무엇을 하는가?

프로젝트/chat-app

react-router로 채팅방 라우팅하기

진!!!!! 2024. 12. 10. 19:39

리액트는 프레임워크가 아닌 라이브러리이므로 내장 라우팅을 지원하지 않는다. 따라서 라우팅을 위해서는 a태그, window.location을 이용하거나, 라이브러리를 이용해야한다.

 

라이브러리를 사용하면 SPA환경에서 페이지 새로고침 없이 필요한 컴포넌트만 렌더링되고, 뒤로 가기/앞으로 가기 등이 더 자연스럽게 동작하기 때문에, 라이브러리를 사용해보기로 했다.

 

Next에서는 Link 컴포넌트 혹은 useRouter 하나면 다 됐는데, 리액트에서는 react-router을 쓸 지 react-router-dom을 쓸 지도 정해야한다.

 

무슨 차이인가 싶어서 찾아본 결과..

react-router-dom이 react-router의 확장된 버전이라고 한다.

  1. react-router
    • 라우팅을 위한 핵심(core) 로직만 포함
    • 모든 React 환경에서 사용할 수 있는 기본 컴포넌트와 훅 제공
    • 직접 사용하기보다는 플랫폼별 패키지의 기반이 되는 패키지
  2. react-router-dom
    • react-router를 포함하고 있음
    • 웹 브라우저 환경에서 필요한 추가적인 기능들을 포함
      • <BrowserRouter>, <HashRouter> 같은 DOM 기반 라우팅 컴포넌트
      • <Link>, <NavLink> 같은 브라우저용 컴포넌트
      • history API와의 통합
      • DOM 이벤트 핸들링

 

react-router-dom 설치

npm i react-router-dom

 

앱 내부 구현

import "./App.css";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import ChatRoomList from "./components/chat/ChatRoomList";
import EmptyChatList from "./components/chat/EmptyChatList";
import ChatList from "./components/chat/ChatList";

const App = () => {
  return (
    <BrowserRouter>
      <div className="flex min-h-screen">
        <div className="w-1/2 p-4">
          <ChatRoomList />
        </div>
        <div className="w-1/2 p-4">
          <Routes>
            <Route path="/" element={<EmptyChatList />} />
            <Route path="/chat/:roomId" element={<ChatList />} />
          </Routes>
        </div>
      </div>
    </BrowserRouter>
  );
};

export default App;

메인 페이지에서, 좌측에는 ChatRoomList가 있고 오른쪽에는 주소에 따라 EmptyChatList 혹은 ChatList가 뜬다.

 //ChatRoomList.tsx
  const fetchChatRooms = async () => {
    const result = await getChatRooms();
    setChatRooms(result);
  };

  useEffect(() => {
    fetchChatRooms();
  }, []);

  return (
	  <div className="p-4">
      {chatRooms.map((chatRoom) => (
        <Link
          to={`/chat/${chatRoom.id}`}
          key={chatRoom.id}
           >
          //내부 컴포넌트
        </Link>
      ))}
    </div>

ChatRoomList에서는 get api를 통해 채팅방 리스트를 불러오고, state로 저장한 후 map과 Link를 이용해 클릭 시 주소가 이동되도록 했다.

 

Link 컴포넌트를 사용하면 브라우저의 주소만 바꾸고 새로 렌더링 되진 않기 때문에, 채팅방을 이동 해도 채팅방 리스트의 값은 유지될 것이라 좋을거라 생각했다.

 

Link 컴포넌트와 NavLink 컴포넌트가 있는데, NavLink 컴포넌트에서는 현재 주소에 따라 스타일링을 지정할 수 있다.

 

Navigating

 

Navigating | React Router

 

reactrouter.com

 

// style
<NavLink
  to="/messages"
  style={({ isActive }) => ({
    color: isActive ? "red" : "black",
  })}
>
  Messages
</NavLink>

Next에서는 현재 페이지 active style을 넣기 위해 매번 className에 삼항연산자를 썼는데…

이런 좋은 기능이 있다니.. 이 기능도 꼭 써봐야겠다.

 

그렇다면 채팅방 이동 시, 자신의 url은 어떻게 알 수 있을까?

const ChatList = () => {
  const { roomId } = useParams();

 

<Route path="/chat/:roomId" element={<ChatList />} />로 설정한 파라미터를 useParams를 이용해 불러오면 된다.

useParams를 이용해 얻은 파라미터를 소켓 주소에 쿼리로 붙여줬다.

const newSocket = io("<http://localhost:3001>", {
      query: { roomId },
    });

 

 

내일은 방 번호에 따라 다른 채팅방 소켓 연결하기로 돌아오겠습니다.

모두 안녕..