[유데미X스나이퍼팩토리] 10주 완성 프로젝트 캠프 프론트엔드(리액트/react) - 20일차 Redux, 웹 소켓

이율곡·2023년 6월 30일
0

부트캠프

목록 보기
20/37
post-thumbnail

20일차

20일차는 Redux에 대해 배웠다. 배우는 동안에 어려웠고, 중요한 내용이라 충분한 복습이 필요할 것 같다는 생각이 들었다. 일단 개념을 이해하는데 어려움이 있었고 코드(action, dispatch)개념도 익숙치 않았다.

그래도 이번 기록을 통해 배웠던 내용을 상기시키고 중요한 내용이었던만큼 보다 나은 다음 주를 대비해야겠다.

git: https://github.com/leeyulgok/4-Day3


수업

Redux

우선 Redux란 JavaScript 애플리케이션에서 클라이언트 측 상태를 관리하기 위한 오픈 소스 JavaScript 라이브러리다. 애플리케이션의 상태를 예측 가능하고 일관된 방식으로 관리하는 데 도움이 된다.

언제 사용하는가

주로 여러 컴포넌트에서 같은 상태를 공유할 때와 애플리케이션의 상태가 복잡하고 많을 때 사용한다. 그 이유는 Redux의 장점 때문인데 Redux의 장점은 전역 상태의 저장소를 제공해주기 때문에 깊이 있는 컴포넌트여도 언제 어디서든 상태에 접근할 수가 있다.

구성요소

Redux는 총 3가지의 구성요소가 있다.

  1. Actions : 애플리케이션에서 무엇이 일어나는지 설명하는 객체.
    모든 action은 type 속성이 필수.
  2. Reducers : 액션에 따라 상태가 어떻게 바뀌는지를 명시하는 함수. 이전 상태와 액션을 인수로 받아 새로운 상태를 반환.
  3. Store : 애플리케이션의 상태를 보유. 애플리케이션의 상태를 조회하거나, 상태를 업데이트하는 액션을 dispatch 할 수 있음.
    +) dispatch : Store에 액션을 보내는 함수. 이 액션은 Reducer로 전달되고, Reducer는 액션 타입에 따라 새로운 상태를 생성.

예시

import React, { useReducer } from "react";

const initialState = 0;

const reducer = (state, action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    case "RESET":
      return initialState;
    default:
      return state;
  }
};

const CountReducer = () => {
  const [count, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <h1>숫자세기</h1>
      <p>: {count}</p>
      <button onClick={() => dispatch({ type: "INCREMENT" })}>증가</button>
      <button onClick={() => dispatch({ type: "DECREMENT" })}>감소</button>
      <button onClick={() => dispatch({ type: "RESET" })}>리셋</button>
    </div>
  );
};

export default CountReducer;

이 코드는 Reducer의 간단한 예시를 나타낸 것이다. 살펴보면 다음과 같다.

우선 reducer 함수다. 이전 상태와 액션을 매개변수로 받아 액션에 따른 상태를 바꿔 값을 리턴해준다.

useReducer는 reducer함수와 초기값을 받는다. 그리고 그걸 상태와 dispatch라는 변수에 저장을 하고 버튼을 클릭했을 때 dispatch를 통해 reducer 함수로 값과 상태를 보낸다.

결과

Socket

소켓은 클라이언트와 서버 간의 양방향 통신을 하게 해주는 통신 도구다. 클라이언트 소켓을 사용하여 서버에 요청을 보내고 서버에서는 요청을 받고 응답해준다. 이 덕분에 우리는 실시간으로 채팅을 하거나 실시간으로 정보를 받을 수 있는 역할을 하게 해준다.

설치

npm i socket.io-client
npm i express socket.io

소켓을 사용하기 위해서는 socket.io를 설치해야 한다. 첫 번째는 React에서 사용하기 위한 설치이고, 두 번째는 백엔드 쪽에서 사용하기 위한 설치이다.

예시

  1. server.js
const express = require("express");
const http = require("http");
const socketIO = require("socket.io");
const cors = require("cors");

const app = express();
app.use(cors());
const server = http.createServer(app);
const io = socketIO(server, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST"],
  },
});

io.on("connection", (socket) => {
  console.log("새로운 클라이언트가 연결되었습니다.");

  socket.on("message", (message) => {
    console.log("새로운 메시지:", message);
    io.emit("message", message);
  });

  // 클라이언트 연결 해제 처리
  socket.on("disconnect", () => {
    console.log("클라이언트가 연결을 해제하였습니다.");
  });
});

server.listen(3001, () => {
  console.log("서버가 3001 포트에서 실행 중입니다.");
});

우선 server.js는 백엔드(서버) 부분이다. 간단하게 설명하면, socket.io를 통해서 클라이언트와 연결하고, emit을 통해 메시지를 주고 받을 수 있게 했다.

  1. chat.js
import React, { useState, useEffect } from "react";
import { io } from "socket.io-client";

const socket = io("http://localhost:3001");

const Chat = () => {
  const [username, setUsername] = useState("");
  const [message, setMessage] = useState([]);
  const [inputValue, setInputValue] = useState("");

  useEffect(() => {
    socket.on("message", sumitHandler);
    return () => {
      socket.off("message", sumitHandler);
    };
  });

  const sumitHandler = message => {
    setMessage((prevMessages) => [...prevMessages, message]);
  }

  const userHandler = (event) => {
    setUsername(event.target.value);
  };

  const messageHandler = () => {
    if (inputValue.trim() !== "") {
      const currentTime = new Date().toLocaleDateString();
      socket.emit("message", {
        username,
        content: inputValue,
        time: currentTime,
      });
      console.log();
      setInputValue("");
    }
  };

  return (
    <div>
      <h1>실시간 채팅</h1>
      <input
        type="text"
        value={username}
        onChange={userHandler}
        placeholder="사용자명"
      />
      <h1>채팅방</h1>
      <div>
        {message.map((m, ind) => (
            <p key={ind}>
                {m.username} : {m.content} - {m.time}
            </p>
        ))}
      </div>
      <input
        type="text"
        value={inputValue}
        onChange={e => setInputValue(e.target.value)}
      />
      <button onClick={messageHandler}>전송</button>
    </div>
  );
};

export default Chat;

chat.js는 클라이언트에서 서버와 주고 받기 위해 서버와 소켓을 연결하고, 화면에 채팅을 띄우는 코드이다. 중요한 부분은 useEffect에서 소켓을 연결하고 끄는 부분이고, messageHandler에서 emit에 어떤 내용을 담을 지를 정하는 부분이 가장 중요하다.

결과


정리하기

20일차는 Redux와 socket에 대해 공부했다. 이 두 가지는 파고들면 파고 들수록 중요하고 어려운 부분이라 한다. 그렇기 때문에 꾸준히 복습을 통해 이 둘을 완벽하게 이해까지는 아니더라도 어떨 때 사용하는지, 효율적인 사용방법은 무엇인지를 알고 넘어가도록 해야겠다.

KPT

Keep

  1. 매일 글쓰기.
  2. 복습하기
  3. 스스로 다른 거 해보기

Problem

  1. 프로젝트 준비하기.

Try

  1. 프로젝트 준비를 위한 리액트 예습하기

본 후기는 유데미-스나이퍼팩토리 10주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.
#프로젝트캠프 #프로젝트캠프후기 #유데미 #스나이퍼팩토리 #웅진씽크빅 #인사이드아웃 #IT개발캠프 #개발자부트캠프 #리액트 #react #부트캠프 #리액트캠프

profile
음악을 좋아하는 사람이 음악을 만들 듯, 개발을 좋아하게 될 사람이 쓰는 개발이야기

0개의 댓글