Archive

Docker - Dockerfile 기본 문법 + 추가 Docker 명령어

|

Docker - Dockerfile 기본 문법 + 추가 Docker 명령어


1. Dockerfile이란?

  • docker 이미지를 작성할 수 있는 기능
  • Dockerfile 문법으로 이미지 생성을 위한 스크립트를 작성할 수 있고, 이를 기반으로 이미지를 생성하고 배포할 수 있다

2. Dockerfile 기본 문법

  • 기본적으로 명령과 인자로 이루어짐
  • 명령은 일반적으로 대문자로 작성
  • 주석은 # 을 붙이고 적는다
  • 반드시 Dockerfile 안에 적는다

  • FROM : 베이스 이미지 지정 명령, ex) FROM alpine

  • LABEL : 버전 정보, 작성자 등 이미지 설명을 작성

    • key=value 형시긍로 메타 데이터를 넣음
    • ex) LABEL version="1.0.0"
  • COPY : 해당 경로에 있는 파일들을 추가함

    • Dockerfile을 기준으로 상대경로로 적는다
  • CMD : docker 컨테이너가 시작할 때, 실행하는 쉘 명령을 지정

    • 배열 형태로 작성하는 방법
      • ex) CMD ["/bin/bash", "-c", "echo", "Hello"]
    • ENTRYPOINT와 함꼐 사용하는 방법
      • ex) CMD ["param1", "param2", ...]
      • ENTRYPOINT가 CMD의 인자로 넘어가서 해당 param을 실행한다
    • 쉘 명령처럼 작성하는 방법
      • ex) CMD <command> <param1> <param2> ...
    • CMD 명령어는 한 Dockerfile 당 한 개만 써야한다
    • 여러개 작성하면 맨 마지막 CMD만 적용된다
  • RUN : 이미지 작성 시 쉘 명령을 실행하는 명령, 일종의 새로운 이미지 레이어를 만드는 역할

    • 보통 베이스 이미지에 패키지를 설치하여, 새로운 이미지를 만들때 사용
    • ex) RUN apt-get update
  • ENTRYPOINT : docker 컨테이너가 시잘할 때, 실행하는 쉘 명령을 지정

    • 이미 쓰여진 CMD 명령에 덮어씌워지지 않는다
    • ex) ENTRYPOINT ["/bin/sh"]
  • EXPOSE : docker 컨테이너 외부에 오픈할 포트 설정

    • 여러개 컨테이너 연결 시 포트를 열어놓기 위해 사용
    • ex) EXPOSE 80
  • ENV : docker 컨테이너 내부에서 사용할 환경변수 지정

  • WORKDIR : docker 컨테이너에서의 작업 디렉토리 설정

    • RUN, CMD, ENTRYPOINT 명령이 실행될 디렉토리 설정
  • COPY : 파일 또는 디렉토리를 docker 컨테이너에 복사, ADD와 달리 URL 지정할 수 없고, 압축 파일을 자동으로 풀어주지 않는다

3. Docker 추가 명령어

  • docker build 옵션 {Dockerfile 경로} : 이미지 빌드
    • -t : 이미지 이름 설정, 저장소(DockerHub ID)/이미지명:태그와 같이 작성
      • 태그 이름이 없는 경우 default로 latest가 붙음
    • -f : 이미지 빌드 시 default로 Dockerfile 파일을 찾아서 빌드한다
      • 그 외 파일명으로 빌드 시 해당 옵션으로 파일명을 지정할 수 있다
    • --pull : FROM으로 지정된 이미지는 한 번 다운로드 받으면, 이미지 생성시마다 새로 다운로드 받지 않고, 다운받은 이미지를 사용한다
      • 해당 옵션은 이미지 생성시마다 새로 다운로드를 받으라는 옵션
      • --pull=true와 같이 사용
      • DockerHub에 배포한 베이스 이미지를 수시로 업데이트하고, 이를 기반으로 새로운 이미지 생성시 자주 사용
  • docker inspect {이미지명} : 이미지에 대한 Config 정보를 JSON 형태로 볼 수 있다(컨테이너도 가능)
  • docker logs {컨테이너 ID or name} : 컨테이너 에러 또는 출력 결과 확인
  • docker kill {컨테이너 ID or name} : stop은 현재 실행중인 단계까지 기다리고 중지하는 반면, kill은 즉시 컨테이너를 중지한다
  • docker history {이미지 or 컨테이너} : 이미지, 컨테이너 히스토리 확인
  • docker cp {컨테이너:경로} {호스트PC경로} : 컨테이너의 특정 파일을 호스트 PC로 꺼내오는 명령
    • ex) docker cp mycontainer:/etc/apache2/site-available/000-default.config ./
    • 반대로 호스트 PC에서 컨테이너에 파일을 넣을 수도 있다
  • docker commit {옵션} {ID or name} {이미지명} : 컨테이너 변경사항을 이미지 파일로 생성
    • -m : 설명 추가
  • docker diff : 본래 이미지와 비교해서 변경된 파일 목록 출력
    • A : 파일 또는 디렉토리 추가
    • D : 파일 또는 디렉토리 삭제
    • C : 파일 또는 디렉토리 수정



참고자료


인프런 - 풀스택을 위한 도커와 최신 서버 기술(리눅스, nginx, AWS, HTTPS, flask 배포) [풀스택 Part3]

Docker - Docker Compose

|

Docker - Docker Compose 작성


1. Docker Compose란?

  • Docker Composes는 여러 컨테이너를 모아서 관리하기 위한 툴
  • FE, BE, DB를 각각 docker 컨테이너로 작성하고, 연결하여 동작하게 하려면 컨테이너 관리 툴이 필요하다
  • Docker Compose는 docker-compose.yml 파일을 작성하여 실행한다
  • docker-compose.yml 파일은 YAML(야멜) 형식으로 작성한다
    • YAML 문법
    • key, value, 들여쓰기를 중심으로 하는 문법
    • --- : 문서의 시작을 나타냄
    • ... : 문서의 끝을 나타냄
    • key:value
    • int, string, boolean 타입 지원

2. Docker Compose 포맷

  • 기본적으로 version, services, volumes, networks 4가지 큰 카테고리로 작성

  • volumes는 컨테이너 설정에서 volumes로 선언이 가능

  • networks는 컨테이너간 네트워크 분리를 위한 추가 설정

  • version

    • Docker Compose 파일 포맷 버전 지정
    • docker 버전에 따라 지원하는 Docker Compose 버전이 있으며 기본적으로 3 사용
  • services

    • 여러개 또는 하나의 컨테이너를 설정

    • build : 이미지를 Dockerfile 기반으로 작성 시 사용

      • context : Dockerfile이 있는 폴더
      • dockerfile: Dockerfile 파일명
    • links : 컨테이너 내부에서 다른 컨테이너를 접속하고 싶을때 사용

    • container_name : 생성될 컨테이너 이름 지정

    • depends_on : 먼저 실행되어야하는 컨테이너 지정

    • image : 베이스 이미지 설정

    • restart : 컨테이너 다운 시, 재시작하는 설정

    • volumes : docker run 옵션의 -v 옵션과 동일

    • environment : Dockerfile의 ENV 옵션과 동일

    • env_file : 환경변수를 담은 파일을 읽어들일 수도 있다

    • ports : docker run 옵션의 -p 옵션과 동일

      • YAML에서는 aa:bb를 시간으로 해석하기에 "aa:bb"로 적는다
    • version: "3"
          
      services:
        app:
          build:
            context: ./경로
            dockerfile: Dockerfile
          links:
            # db 컨테이너를 app 컨테이너에서 사용 (mysqldb 이름으로)
            - "db:mysqldb"
          ports:
            - "80:8080"
          container_name: appcontainer
          depends_on:
            # db 컨테이너 생성 후 app 컨테이너 실행
            -db
        db:
          image: mysql:5.7
      	restart: always
      	volumes:
      	  - ./mysqldata:/var/lib/mysql
      	environment:
      	  - MYSQL_ROOT_PASSWORD=123123
      	  - MYSQL_DATABASE=mywebdatabase
          env_file:
      	  - ./mysql_env.env
      	ports:
      	  - "3306:3306"
          container_name: dbcontainer
      

3. Docker Compose 주요 명령어

  • docker-compose up : docker 이미지를 만들어 실행
    • -d : 백그라운드로 실행
    • --build : 재빌드 시 옵션 추가, 안적으면 이미 작성된 이미지를 사용
  • docker-compose stop : 중지
  • docker-compose down : up 명령으로 생성된 컨테이너 삭제
  • docker-compose logs : 각 컨테이너의 모든 로그 출략
  • docker-compose config : 실행중인 Docker Compose의 docker-compose.yml 설정 확인
  • docker-compose exec 컨테이너명 : 실행중인 컨테이너에 명령어 실행

4. dockerignore

  • .dockerignore 파일을 작성하면 그 폴더를 COPY 할 시, 특정 파일/폴더를 제외하고 복사할 수 있게 해준다



참고자료


인프런 - 풀스택을 위한 도커와 최신 서버 기술(리눅스, nginx, AWS, HTTPS, flask 배포) [풀스택 Part3]

리눅스 쉘(Shell) 기본적인 사용법

|

리눅스 쉘(Shell) 기본적인 사용법


1. 리눅스 기본 명령어 정리

  • whoami : 로그인한 사용자 id를 알려준다 (root: 슈퍼관리자, 사용에 주의)
  • sudo : root 권한으로 실행
  • pwd : 현재 디렉토리 위치
  • ls : 파일 목록 출력, (ls -al : 숨김파일, 폴더까지 포함하여 출력)
  • 파일 권한 : 읽기, 쓰기, 실행에 대한 권한을 소유자, 그룹, 기타로 보여줌 ex ) drwxr-xr– :
    • 맨 앞의 d는 디렉토리, -는 파일
    • 소유자 : rwx 읽기,쓰기,실행 모두 가능
    • 그룹 : r-x 읽기, 실행만 가능
    • 기타 : r– 읽기만 가능
    • rwx : 4 , 2, 1 순으로 이것을 조합하여 숫자로 나타낸다
    • 위의 예를 숫자로 표현하면 754
  • chmod : 파일 권한 변경
    • ex ) chmod -R 777 {directory}
  • cat : 파일 보기
  • rm : 파일 및 폴더 삭제
    • -r : 하위 디렉토리를 포함한 모든 파일 삭제
    • -f : 강제로 파일이나 디렉토리 삭제
    • ex ) rm -rf {파일 및 폴더명}
  • head : 파일의 앞 라인 10개만 보여준다
  • grep {검색명} : 검색명을 가진 것들을 추린다
    • -i : 영문 대소문자 구별 X
    • -v : 패턴을 포함하지 않는 라인을 출력
    • -n : 검색 결과에 행 번호를 삽입
    • -l : 파일명만 출력
    • -c : 패턴과 일치하는 라인의 개수만 출력
    • -r : 하위 디렉토리까지 검색
  • ps : 프로세스 상태 확인
    • -a : 시스템을 사용하는 모든 사용자의 프로세스 출력
    • -u : 프로세스 소유자에 대한 상세정보 출력
    • -l : 프로세스 관련 상세정보 출력
    • -x : 데몬 프로세스까지 출력, 현재 쉘에서 실행한 프로세스 이외에 모든것
    • -e : 해당 프로세스 관련 환경변수 정보도 출력
    • -f : 프로세스간 관계 정보도 출력
    • ex ) ps aux
  • kill : 프로세스 중지
    • ex) kill -9 {프로세스 id or 작업번호}
    • -9 : 작업 강제 종료
  • cp : 파일 복사
    • ex ) cp test.txt copy.txt => test.txt를 복사하여 copy.txt를 만듦
    • ex ) cp -rf * {폴더명} => 하위 폴더 포함 모두 복사


2. 리다이렉션과 파이프

  • Standard Stream : 표준 입출력
    • command로 실행되는 프로세스는 세 가지 스트림을 가지고 있다
    • 표준 입력 스트림 (Standard Input Stream) - stdin
    • 표준 출력 스트림 (Standard Output Stream) - stdout
    • 오류 출력 스트림 (Standard Error Stream) - stderr
  • 이 스트림을 바꿔줄 수 있는게 리다이렉션과 파이프이다
  • 리다이렉션 : >, <를 사용함 (재실행시 덮어쓴다)
    • 명령어 표준 출력을 화면이 아닌 파일에 쓸 때 사용한다
    • ex ) ls -al > test.txt (ls의 결과가 test.txt에 저장됨)
    • ​ cat test.txt
    • >> 키워드는 덮어쓰지 않고 이어서 쓴다
  • 파이프 : | 를 사용함
    • 선행 명령어의 출력이 후행 명령어의 입력으로 들어간다
    • ex ) ls -al | grep bash
    • ls -al의 결과물 중에 bash라는 이름을 가진 것들만 추린다


3. 프로세스

  • foreground process : 쉘에서 명령 실행 후, 해당 프로세스 수행 종료까지 사용자가 다른 입력을 할 수 없음
    • ctrl + c 로 프로세스 종료
  • background process : 사용자 입력과 상관없이 실행되는 프로세스
    • 해당 프로세스 실행 시, 맨 뒤에 & 을 붙인다


4. 하드링크와 소프트링크

  • ln A B : 하드링크로 복사하여 파일을 만든다. A를 수정하면 B도 수정된다
    • ex ) ln a.txt b.txt
  • ln -s A B : 소프트(심볼릭)링크 복사하여 파일을 만든다. (윈도우의 바로가기랑 비슷)
    • ls -al 명령어로 소프트링크 확인 가능
    • A를 삭제하면 B도 접근이 불가능하다


5. 우분투 패키지 관리

  • CentOS, Fedora 등 RedHat 계열 배포판은 RPM이라는 패키지 시스템을 사용한다
  • ubuntu와 같이 데비안 계열 배포판은 dep이라는 패키지 시스템을 사용한다
  • apt 명령어를 주로 사용한다
  • sudo apt-get update : 패키지 인덱스 정보 업데이트
  • sudo apt-get upgrade : 설치된 ubuntu 패키지 업그레이드 (함부로 사용 X)
  • sudo apt-get install {패키지명} : 패키지 설치
  • sudo apt-get remove {패키지명} : 패키지 제거
  • sudo apt-get --purge remove {패키지명} : 패키지 제거 (설정파일 포함)


6. VIM 에디터 기본 사용법

  • VIM : 기존 vi 에디터의 improved version
  • vi에 자동화, 시각화 메뉴 등을 추가했음
  • 일반 모드 : vim 처음 실행 시 or 편집, 명령 모드에서 ESC 입력 시 (찾기, 커서 이동 등)
  • 명령 모드 : 일반 모드에서 : 입력 시 (저장, 파일읽기, vim 설정 등)
    • wq : 저장 후 종료
    • q! : 저장하지 않고 강제 종료
  • 편집 모드 : 일반 모드에서 a 또는 i 또는 o 입력 시 (텍스트 입력 / 편집)
  • 비쥬얼 모드 : 일반 모드에서 v 입력 시 (블럭 복사 / 붙여넣기)



참고자료


인프런 - 풀스택을 위한 도커와 최신 서버 기술(리눅스, nginx, AWS, HTTPS, flask 배포) [풀스택 Part3]

Docker - 설치 및 기본 명령어

|

Docker - 설치 및 기본 명령어


1. Docker 설치 [리눅스용]

  • AWS EC2 ubuntu 20.04를 기준으로 한다
  • 최신 패키지와 리스트 업데이트를 진행한다 sudo apt update
  • https 관련 패키지를 설치한다 sudo apt install apt-transport-https ca-certificates curl software-properties-common
  • docker repo 접근을 위한 GPG key 설정을 한다 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  • docer repo 등록 sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
  • sudo apt update로 docker repo까지 포함하여 최신 패키지 리스트 업데이트
  • docker 설치 sudo apt install docker-ce
  • docker 실행 확인 sudo systemctl status docker

  • 매번 sudo를 사용하면 귀찮으므로 docker group에 포함시킨다
  • 현 사용자(ubuntu) ID를 docker group 그룹에 포함 sudo usermod -aG docker ${USER}
  • 터미널 재접속
  • 현재 로그인된 ID가 docker group에 포함되어있는지 확인 id -nG
  • docker 그룹에 포함되어 있다면, sudo 없이 docker 명령어 사용이 가능하다

  • docker-compose 설치

    sudo curl -L "https://github.com/docker/compose/releases/download/1.28.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

  • 위 1.28.2는 강의와 같은 환경을 위해 설정하였지만 최신버전은 docker compose늬 릴리즈노트를 보고 바꾸면 된다

  • 실행 권한 주기 sudo chmod +x /usr/local/bin/docker-compose

  • docker 버전 확인으로 설치가 잘 되었는지 확인 docker-compose --version


2. Docker 주요 명령어

  • sudo systemctl status docker : docker 실행중인지 확인

  • docker login : cli 사용을 위해 로그인 필요

  • docker search {검색명}:[태그명] : docker hub에서 image 검색
    • --limit=5 : 검색 결과를 5개로 추려서
    • [OFFICIAL] : 공식 이미지
    • 태그명 안붙이면 default로 :latest가 된다
  • docker pull {이미지명} : 해당 이미지를 다운로드

  • docker images : 다운로드 받은 이미지 리스트를 출력
    • -q : 리스트 중 IMAGE ID만 추려서 출력
  • docker image rm {이미지:태그} : 다운로드 받은 이미지 삭제
    • {IMAGE ID} 로도 삭제 가능, 겹치지 않는 앞부분만 적어도 됨
    • docker rmi 도 동일한 기능
  • docker create {이미지명} : 이미지로 컨테이너 생성
    • 이미지는 컨테이너로 생성해야 실행이 가능하다
    • –name {컨테이너이명} : 컨테이너명을 주고 컨테이너 생성
  • docker ps : 현재 실행중인 컨테이너 리스트 출력
    • -a : 실행중이지 않은 리스트까지 포함해서 출력
    • -q : 컨테이너 아이디만 출력
    • 하나의 이미지로 여러 컨테이너 생성 가능
  • docker rm {컨테이너명 or 컨테이너 ID} : 컨테이너 삭제
    • 이미지명을 적지 않도록 주의
  • docker start {컨테이너명} : 컨테이너 시작

  • docker run : 우분투 자체만 컨테이너를 만들 경우, 터미널 및 입력을 연결해주어야함

    • 우분투 컨테이너의 입력을 가상 터미널에 할당해주어, PC 상에서의 입력이 우분투 컨테이너 입력에 들어갈 수 있게 해줌

    • 우분투 컨테이너의 bash 쉘은 입력을 받을 수 있는 상태로, 종료되지 않고 실행중 상태가 됨

    • -i : 컨테이너 입력을 열어놓는 옵션

    • -t : 가상 터미널을 할당하는 옵션 (주로 -it 옵션 같이 사용)

    • --name : 컨테이너 이름을 설정하는 옵션

    • -d : 컨테이널르 백그라운드에서 실행하는 옵션

    • --rm : 컨테이너 종료 시 컨테이너를 자동으로 삭제하는 옵션

    • -p : 호스트와 컨테이너 포트를 연결하는 옵션

      • docker를 실행한 PC를 Host PC라고 한다

      • apache, nginx 등 웹서버 컨테이너 실행 시, Private IP가 할당되어 외부에서 접근이 불가능하다 (172.17.0.0 ~ 172.17.255.255)
      • 호스트 PC IP에 특정 port로 접근 시, 해당 port를 docker 컨테이너의 특정 Private IP의 특정 port로 변환해주는 것을 NAPT(Network Address Port Translation)라 하고 도커의 내부적인 기능이다
      • docker run -d -p 9999:80 --name mywebserver httpd Host PC의 9999 포트로 접속하면, 이를 mywebserver 컨테이너의 80 포트로 포트워딩을 해준다는 의미
    • -v : 호스트와 컨테이너 디렉토리를 연결하는 옵션

    • -it 옵션의 의미 :

      • pseudo tty(teletypewriter) : 리눅스에서 콘솔, 터미널을 의미
      • tty를 통해 리눅스에 키보드 입력을 전달할 수 있으며, 두번째 tty부터 가상의 tty라고 한다
      • docker 컨테이너에 표준 입력을 열어놓고, pseudo tty를 만들어 표준 입력을 pseudo tty에 연결
      • 따라서, 키보드 입력을 pseudo tty를 통해, 컨테이너의 표준 입력으로 전달할 수 있도록 해준다
    • pull + create + start를 run 명령어로 한방에 해결 가능

  • docker stop {ID 혹은 name} : 해당 컨테이너 종료 / restart로 재시작

  • docker pause {ID 혹은 name} : 해당 컨테이너 일시정지 / unpause로 일시정지 해제

  • docker system df : 사용하고 있는 이미지, 컨테이너 등 저장매체 현황 확인

    • ubuntu는 크기가 커서 초경량 시스템을 위한 리눅스 패키지인 alpine 태그가 붙은 이미지를 사용한다
    • ex) docker run httpd:alpine
  • docker container stats : 실행중인 컨테이너의 리소스 사용현황을 확인

  • docker exec {name} /bin/bash : 외부에서 컨테이너 진입 시 사용

    • alpine의 경우 /bin/sh
    • 터미널 여러개 키고 작업 시 사용하면 편리하며 attach로 접근하면 기존 실행한 터미널의 컨테이너는 꺼진다
  • docker attach {ID 혹은 name} : 백그라운드로 실행한다면 쉘 입력이 불가능하기 때문에 명령어로 해당 컨테이너에 연결하여 입력이 가능하도록 한다

  • docker stop $(docker ps -a -q) : 모든 컨테이너 중지

  • docker rm $(docker ps -a -q) : 모든 컨테이너 삭제

  • docker rmi -f $(docker images -q) : 모든 이미지 삭제



참고자료


인프런 - 풀스택을 위한 도커와 최신 서버 기술(리눅스, nginx, AWS, HTTPS, flask 배포) [풀스택 Part3]

React에서 Typescript 사용하기 - 3

|

React에서 Typescript 사용하기 - 3


1. reducer

  • 액션 타입을 정의한다
  • 각 액션에 대한 인터페이스를 정의한다
  • 액션이 많을 경우 type으로 묶는다

  • initialState에 대한 type을 정의한다
  • reducer의 매개변수인 state, action에 대한 타입을 설정하고 return type도 state와 동일하게
  • Action 타입과 Action에 대한 인터페이스는 프로젝트 성격에 맞게 따로 빼서 저장할 수도 있다
// 액션타입 정의
export enum ActionType {
  SEARCH_REPOSITORIES = 'search_repositories',
  SEARCH_REPOSITORIES_SUCCESS = 'search_repositories_success',
  SEARCH_REPOSITORIES_ERROR = 'search_repositories_error'
}

// 액션에 대한 인터페이스
interface SearchRepositoriesAction {
  type: ActionType.SEARCH_REPOSITORIES;
}

interface SearchRepositoriesSuccessAction {
  type: ActionType.SEARCH_REPOSITORIES_SUCCESS;
  payload: string[];
}

interface SearchRepositoriesErrorAction {
  type: ActionType.SEARCH_REPOSITORIES_ERROR;
  payload: string;
}
// 위 3개를 하나로 묶어서 사용하면 편리
export type Action = 
  | SearchRepositoriesAction 
  | SearchRepositoriesSuccessAction 
  | SearchRepositoriesErrorAction;

// state에 대한 타입 정의
interface RepositoriesState {
  loading: boolean;
  error: string | null;
  data: string[];
}

const initialState = {
  loading: false,
  error: null,
  data: [],
};

const reducer = (
  state: RepositoriesState = initialState, // state 타입 설정
  action: Action // action 타입 설정
  ): RepositoriesState => { // retrun 타입 설정
  switch (action.type) {
    case ActionType.SEARCH_REPOSITORIES:
      return {
        loading: true,
        error: null,
        data: [],
      }
    case ActionType.SEARCH_REPOSITORIES_SUCCESS:
      return {
        loading: false,
        error: null,
        data: action.payload,
      }
    case ActionType.SEARCH_REPOSITORIES_ERROR:
      return {
        loading: false,
        error: action.payload,
        data: [],
      }
    default:
      return state;
  }
};

export default reducer;


2. action

  • redux-thunk 사용
  • dispatch의 타입은 redux의 Dispatch, 제네릭으로 들어갈 action 타입을 넣는다
import axios from 'axios';
import { Dispatch } from 'redux';
import { ActionType } from '../action-types';
import { Action } from '../actions';

export const searchRepositories = (term: string) => {
  return async (dispatch: Dispatch<Action>) => {
    dispatch({
      type: ActionType.SEARCH_REPOSITORIES
    });

    try {
      const { data } = await axios.get('https://registry.npmjs.org/-/v1/search', {
        params: {
          text: term
        }
      });

      const names = data.objects.map((result: any) => {
        return result.package.name;
      });

      dispatch({
        type: ActionType.SEARCH_REPOSITORIES_SUCCESS,
        payload: names
      });
    } catch (err: any) {
      dispatch({
        type: ActionType.SEARCH_REPOSITORIES_ERROR,
        payload: err.message
      });
    }
  };
};


3. store

  • react와 같다
// app.tsx
import { createStore, applyMiddleware } from "redux";
import thunk from 'redux-thunk';
import reducers from "./reducers";
import { Provider } from 'react-redux';
import { store } from '../state';
import RepositoriesList from './RepositoriesList';

export const store = createStore(reducers, {}, applyMiddleware(thunk));

function App() {
  return (
    <Provider store={store}>
      <div>
		{/* ... */}	
      </div>
    </Provider>
  )
}

export default App;


4. useSelector

  • useSelector의 state => state.{name}을 typescript가 인식하지 못함
  • react-redux 패키지의 TypedUseSelectorHook을 사용하여 custom hook을 만들 수 있다
  • TypedSelectorHook의 제네릭에 RootState를 설정하는데 combineReducers에서 묶어준 reducer들을 ReturnType으로 넣어준다
import { combineReducers } from "redux";
import repositoriesReducer from "./repositoriesReducer";

const reducers = combineReducers({
  repositories: repositoriesReducer,
});

export default reducers;
// RootState를 설정하여 TypedUseSelectorHook에서 사용한다
export type RootState = ReturnType<typeof reducers>;


// useTypedSelector.ts

import { useSelector, TypedUseSelectorHook } from "react-redux";
import { RootState } from "../state";

export const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;


// useTypedSelector 사용
import { useTypedSelector } from '../hooks/useTypedSelector';

const RepositoriesList:React.FC = () => {
  const { searchRepositories } = useActions();
  const { data, error, loading } = useTypedSelector(state => state.repositories);
  
  return (
    <div>
		{/*...*/}
    </div>
  )
}

export default RepositoriesList;


5. +보너스 액션 dispatch시 편리하게 사용하기

  • 액션들을 한데 묶어서 편리하게 사용할 수 있다
  • redux 패키지의 bindActionCreators를 사용한다
  • 이를 이용해 custom hook을 만들 수 있다
import { useDispatch } from 'react-redux';
import { bindActionCreators } from 'redux';
import { actionCreators } from '../state'; // 액션들

export const useActions = () => {
  const dispatch = useDispatch();

  return bindActionCreators(actionCreators, dispatch);
  // bindActionCreators 사용하면 dispatch에 액션이 담긴 함수를 반환
  // { searchRepositories: dispatch(searchRepositories}
};

// 컴포넌트에서 다음과 같이 사용할 수 있다
const { searchRepositories } = useActions();
searchRepositories(value);



참고 자료


udemy - React and Typescript: Build a Portfolio Project