2주차(목) - 프리 온보딩 코스 프론트엔드 - Redux

💫 2주차(월) 과제 리뷰

CSS 디테일이 떨어지는 경우 (감점사항)

  • 예시: 여백, 체크박스 네모의 크기, cursor:pointor

컨벤션, 협업 규칙을 정하지 않은 경우

TypeScript 아쉬운점

  • union, optional 너무 많이사용 ⇒ 자유도 높아짐 ⇒ 안좋음🚨

  • 타입을 시작할때부터 정의를 잘하고 가는게 좋다

  • 각자 맡은 컴포넌트에서 코드 중복 ⇒ 협업이 잘 안된다고 생각함 ❌

  • 하나에서만 쓰는 props type을 공용 파일에 정의하는 경우

    • 응집도를 최대한 생각하는게 좋음
    • 한 파일 안에서만 쓰이면 따로 분리하지 않아도 좋다

좋은코드 작성하기

  • 의도가 드러나는 이름(변수명)을 작성하자

  • IProps(요즘은 유행 지남) ⇒ 팀 안에서 정하는 컨벤션이 가장 높은 우선순위

    • 요즘에는 MaterialProps 등으로 사용
  • hooks를 쓰려는 노력

💁🏻‍♂️ 멘토 가이드

  • 요즘 redux보다 recoil을 쓰는 회사가 점점 많아지고 있다

  • 리덕스를 할줄 아는 주니어를 정말 요구함

    • 붓캠 나왔는데 리덕스를 안하고 왔다고? ⇒ 대부분 면접관이 이렇게 생각함
    • 아무래도 한번이라도 경험 있는 사람 ✨
  • 리액트 네이티브

    • 커뮤니티가 아주 크다

    • 실제로 우리나라도 채용중인 곳이 있어서 (짧은 설명 할 예정)

📎 학습 자료

🏅 Redux

Data Binding

  • 뷰(화면)과 모델(데이터)을 연결하는 것을 의미.

  • jQuery는 데이터 바인딩이 안되어 있었다.

  • 직접 돔 조작을 해야 했었음 ㅜ

단방향(One way Data Binding, Unidirectional Data Flow)

  • 데이터의 흐름: 모델 → 뷰 (리액트)

  • input에 사용하는 state 업뎃할 때 어떻게 했었죠?

    • 단방향이었기 때문에 그렇게 했던 것

양방향(Two way Data Binding)

  • setState 할 필요가 없음 ⇒ 쓰면 그 순간에 모델을 바꾼다

  • 모델이 바뀌면 뷰가 바뀌고 뷰가 바뀌면 모델이 바뀐다

🏅 MVC Pattern

  • 서로 관심이 다른 것을 분리해서 코드의 단순화 및 유지보수의 자유도가 생긴다.

  • 관심사가 잘 분리되면 독립적, 모듈 재사용을 위한 높은 자유도가 향상된다.

  • 과거부터 사용한 오래된 패턴 (Model, View, Controller)

  • 단점🚨 View 가 많아지면 유지보수 하기 어렵다

Model

  • 데이터라고 생각하면 된다. json 또는 데이터 모델 정의.

  • 일반적으로 데이터를 처리하는 로직과 함께!

View

  • 화면, html, 레이아웃 이라고 생각하면 된다.

Controller

  • 이벤트 핸들러와 이벤트를 처리하는 로직이 있는 곳이라고 생각하면 쉽다.

  • 데이터랑 뷰 이어주는 역할.

  • 요청이(이벤트 발생) 오면 모델에 적절한 로직을 실행하도록 한다.

🏅 Flux Pattern

👩🏻‍💻 Flux는 개발이 오래되고 커져도 유지보수가 쉽고 reliable하고 high performance를 유지하는 새로운 패턴을 제시했습니다.

Redux는 Flux 패턴에 기반한 라이브러리이므로 Flux 패턴을 이해하고 넘어갈 필요가 있습니다!

기존 MVC의 문제점

  • 프로젝트 규모가 커질수록 빠르게 복잡해진다.

  • feature 추가될 때마다 모델과 뷰를 연결하는 복잡성이 증가한다.

  • 데이터 간의 의존성과 연쇄적인 갱신은 뒤얽힌 데이터 흐름을 만들고 예측할 수 없는 결과로 이끌게 된다.

  • 복잡성이 증가할 수록 예측 불가능해지고 안정성이 떨어진다. (어디서 버그가 터져나올지 테스트도 어렵다..)

Flux

  • 단방향 데이터 흐름(unidirectional data flow)이 핵심.

  • 사용자에 의해 Action이 발행되면, 해당 Action에 영향이 있는 모든 View가 갱신(rerender)된다. 어디에서 어떤 일이 일어날지 알 수 있다 (=예상가능하다. 복잡하지 않다). 흐름은 하나니까!

  • Flux는 세 가지 부분으로 구성 되어 있다.
    1. Dispatcher
    2. Stores
    3. Views(리액트 컴포넌트)

Dispatcher

  • dispatcher를 통해 action을 발행한다.
  • 모든 데이터는 중앙 허브인 dispatcher를 통해 흐른다.

Store

  • 어플리케이션의 데이터와 비지니스 로직을 가지고 있는 store
  • 큰 프로젝트 에서 전체 state를 가지고 있는 데이터 저장소

Views

  • action이 발행되면 이 action에 영향이 있는 모든 view가 갱신됨

🏅 Redux Intro

👨🏻‍💻 Redux는 Flux 패턴을 근본으로한 라이브러리이다.
React 뿐 아니라 다른 UI 라이브러리에서도 사용할 수 있다.

Why Redux?

  • 우리는 언제 리덕스를 써야하는지 알 필요가 있다

    • 컴포넌트끼리 데이터 주고받을 일이 많다
    • Bottom to top 데이터 전송 할일이 많다
    • localStorage, Session, Redux 등 저장할 공간에
  • 수업시간에 찾은 예시

    • 다크모드, 언어설정(url로 관리) ⇒ 리프레시 하더라도 유지되야함

    • 장바구니 ⇒ 담을때마다 api호출해서 저장한다

      • 어떻게든 사게끔 하려면 비즈니스 적으로 진짜 중요한기능
    • admin페이지 option? 조금 애매함 ⇒ 한 페이지에서만 쓰일 것 같아서

  • ⚠️ 언제 Redux를 써야할지 위의 기준으로 생각하자. 아무데서나 쓰지 말자.

Redux

Store

  • Application의 전체 state는 store라고 불리는 곳에서 관리된다.

  • store는 redux의 상태값(state)를 갖는 객체이다.

Action

  • action은 state 변화를 일으킬 수 있는 행동정보, 현상등이라고 생각하면 된다.

  • 다크모드에서 다크로 눌렀다 ⇒ 이 자체가 액션

Dispatcher

  • action이 일어나면 Dispatcher를 통해서 store의 state가 업뎃된다.

  • 액션을 받아서 dispatcher가 감지를 하고 store안에 있는 정보를 바꿔준다

View

  • state가 변경되면 view에서 감지하고, 화면에 반영(rerender) 된다.

  • 위의 그림과 같이 view단에서 action이 일어날 수도 있다(당연). view에서 action이 일어나면 -> 다시 dispatcher에 의해 store에 저장되고 -> state가 변경되면 -> 필요한 view에서 감지를 알아차린다.

Redux의 세 가지 원칙

1. 전체 상태값이 하나의 객체로 표현됨

  • 간단히 말하면 하나의 React앱에 store가 하나라는 뜻임

2. 상태값(state)는 읽기 전용이다.

  • 원래 컴포넌트에서의 state 관리 생각하시면 됩니다.

3. 상태값(state)은 순수 함수에 의해서만 변경되어야 한다.

  • 상태값(state)을 변경시키려면, 상태값을 변경하는 함수가 필요합니다.

  • 이 함수를 reducer라고 하고, 이 함수가 순수함수(pure function) 이어야 한다는 말.

    • 🤔 순수함수란? 항상 같은 입력이 있으면 같은 결과를 반환해야한다.

👀 FAQ

🏅 Redux 사용 | Reducer Store Action

왜 모달로 예시를 잡았냐?

  • 만약에 클릭했으면 모달을 열고, 안열고

  • 나중에 html을 보면 모달이 button 옆에 생긴다 ⇒ 사실상 이렇게 있으면 안된다

  • 정상적인 모달의 위치는 ⇒ 가장 상단의 div이다 ⇒ 하나만 있어야 한다!!

    • 요소 근처에 있으면 안된다
    • portal ⇒ 미리 상단에 div를 만들어준다 ⇒ 어느 컴포넌트에서 모달을 키건 간에 우리가 만들어 놓은 곳에 생긴다

Redux 구성 요소 - Action

사용자의 입력이나 UI 조작, 웹 요청 완료같이 어떠한 상태 변화를 일으킬 수 있는 현상. 즉, 어떤 조작인지 정보를 갖고 있는 자바스크립트 객체이다.

Action의 생김새

  • 타입이라는 프로퍼티가 필수이다, 대문자로 넣어준다
{
    type: 'SHOW_MODAL'
}

Action 특징

다음과 같은 특징이 있다. 이것만 기억하면 쉽다!

  1. action은 객체이다.
  2. action은 반드시 type 프로퍼티가 있어야 하고,
    일반적으로 type은 어떤 행동을 설명하는(조작하고 싶은 내용) 문자열이다.
  3. type 이외에 다른 프로퍼티를 가져도 되고,
    주로 해당 action에 필요한 부가적인 데이터를 전달하고 싶을 때 사용한다.

Action 정의

react 프로젝트에서 사용할 action은 객체 리터럴로 바로 정의하는 것이 아니라, action을 만들어주는 함수를 통해 만든다. 이러한 함수를 Action Creator(액션 생성자)라고 한다.

// showModal이 Action 생성자
function showModal() {
	return { type: 'SHOW_MODAL'}  // <- Action!
}

Action은 일반적으로 '행동 정보'인 type만 갖고 있지는 않고, 부가적인 정보를 포함하고 있다.

  • show가 있으면 close도 있어야 한다
  • contents 같이 자세한 내용까지 보내줄 수 있다
function showModal({ title }) {
	return { type: 'SHOW_MODAL', title }
}

Redux 구성 요소 - Reducer

reducer는 action이 발생했을 때 state를 변화시키기 위한 함수이다. 즉, reducer는 새로운 state를 반환하는 함수!

  • 🤔 오 이렇게 액션이 들어왔으니 우리 상태를 이렇게 바꿔볼까??

Reducer의 생김새

reducer는 현재의 state와 action을 인자로 받고, 이 action의 내용(type)에 따라 state를 변화시킨다.

  • 지금 스테이트와, 액션을 받고 바뀐 스토어를 반환한다
(state, action) => nextState

Reducer 정의

  • 액션 타입을 받아서 이럴땐 이렇게 저럴땐 저렇게

  • 우리는 이전의 상태에서 원하는 부분만 변화해서 반환한다

function modal(state, action) {

  switch(action.type) {
    case 'SHOW_MODAL':   // SHOW_MODAL 이라는 action이 발행되면
      return {
        ...state,
        showModal: true  // 전역 state 중에서 showModal의 값을 true로 바꾼다.
      };
    default:
      return state;
  }

}

Redux 구성 요소 - Store

store는 앱에 오직 하나만 있고, 이 유일한 store를 사용하여 app의 전체 상태를 관리 한다.

  • 리덕스 통해서 스토어를 만들고 만든 리듀서를 스토어 안에 넣어준다
//index.js
import { createStore } from 'redux'
import modalReducer from './ModalReducer';

const store = createStore(modalReducer);
  • redux에서 제공하는 createStore 함수 생성

  • store를 생성할 때 reducer를 인자로 전달하면 된다.

🏅 redux-saga

  • 리덕스만 가지고서는 비동기 처리가 불가능하다

    • 중간에 유저가 바뀌거나 했을때 API를 다시 호출해야 한다??
    • middleware가 없으면 불가능 하다
  • thunk보다 saga가 훨씬 기능이 많고 요즘에 많이 쓰는 추세이다

    • saga 초기셋팅 어렵다고 한다 🥲

middleware

  • 중간에 처리하는 로직

  • route 처리, 오류 처리, 등등등 응답요청 사이에 다양한 기능을 추가할 수 있다.

  • action과 redcer 사이에서 일어나는 일들 에서 middleware 사용 👀 (로그 남기기, 비동기 처리)

generator (ES6)

  • generator를 왜 가져왔냐,,

    • 엄청 복잡한 개념이다.. 쓰는거는 간단하다?
    • saga를 구성하는 중요한 요소
    • 객체를 반환하는데 next라는 문법이 있다 (호출하면 반환하고 멈춘다)
  • generator함수를 만들 때는 function* 키워드를 사용합니다. (잘 이해 못해도 redux-saga 사용가능)

  • generator함수를 호출하면 객체를 반환하는데, 그 객체에 next라는 key가 있고, next메서드를 호출하면 다시 객체를 반환합니다.

  • 참고

    • generator 함수는 iterator이다.
    • iterator는 next라는 key를 갖고 있는 객체이다.
    • next함수를 실행하면 객체를 반환하는데, 그 객체는 value와 done이라는 property를 가지고 있다.
    • generator와 함께 공부할 키워드 🏅 ⇒ 면접 준비하려면 이거 필수
      • iterator
      • iterable
      • for .. of
      • 전개 연산자
      • Symbol
      • Symbol.iterator

redux-saga

  • redux-saga에서 말하는 side effect는 (부정적인 의미의) 부작용이 아니라, 긍정적인 부수효과를 의미합니다.

  • 다양한 기능들이 있기 때문에 내가 구현하고 싶은 기능에 따라 사용하면 됩니다.

  • 예시) 토스트가 올라왔다가 3초만에 없애고 싶다
    - saga 같은 걸로 가능하다 비동기 처리!

🏅 Context API

  • 회사에서 redux랑 추가적으로 조합을 쓸 경우가 있다

Context / Provider / Conumer

  • Context를 간단히 설명하자면 크게 Provider와 Consumer로 나뉩니다.

  • Provider는 전역 상태를 정의하고, 전역 상태를 update하는 로직이 있습니다.

  • Consumer로 전역 상태를 사용할 수 있습니다.


좋은 웹페이지 즐겨찾기