React TIL 08

Nabang Kim·2021년 8월 13일

React

목록 보기
8/8
post-thumbnail

2021년 8월 13일에 작성된 문서 1번 입니다.
React 배운 내용을 정리했습니다.



Redux란?

Redux: 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너 Redux는 여러분이 일관적으로 동작하고, 서로 다른 환경(서버, 클라이언트)에서 작동하고, 테스트하기 쉬운 앱을 작성하도록 도와줍니다. 여기에 더해서 시간여행형 디버거와 결합된 실시간 코드 수정과 같은 훌륭한 개발자 경험을 제공합니다.

Redux의 정의

  • 자바스크립트 SPA가 점점 복잡해져서 많은 상태를 자바스크립트 코드로 관리할 필요가 생김.
    • 상태:
      • 서버응답, 캐시데이터, 지역적으로 생성해서 사용하고 있지만 아직 서버에 저장되지 않은 데이터.
      • 활성화된 라우트, 선택된 탭, 로딩을 보여줄지 여부, 페이지네이션 컨트롤 등 다양한 UI 상태도 포함



Redux와 React를 함께 쓰면?

  • Redux는 애플리케이션의 상위에 자리잡은 Store를 만들어서 다른 모든 컴포넌트로 State를 공급.
    • Store : 데이터를 전역에서 관리하는 곳
    • Reducer : 내부에 Action에 따른 데이터 값을 변화시켜주는 순수함수

Redux와 함께 사용한다면 React의 단점을 보완해줄 수 있다.

  • react 장점: 직관적이고 관리하기가 편함.
  • react 단점: 컴포넌트들이 많아졌을 때, 상위컴포넌트에서 데이터가 하위컴포넌트로 움직이는 단일 구조적 부분들이 관리할 때 불필요한 복잡성이 생길 수 있다.



Redux의 3원칙

1. 진실은 하나의 근원으로부터

  • 애플리케이션의 모든 상태하나의 저장소 안, 하나의 객체 트리구조로 저장.
    • 하나의 코드 베이스 ⇒ 다양한 환경에서 실행 가능한 코드(universal application) 쉽게 만듦.
    • 하나의 상태 트리디버깅에도 용이, 빠른 개발 사이클을 위해 개발중 애플리케이션 상태 저장 가능.
    • 하나의 상태 트리실행취소/다시실행(undo/redo)를 손쉽게 구현.
console.log(store.getState());

/* 
{
  visibilityFilter: 'SHOW_ALL',

  todos: [ //아래의 객체를 담은 배열.
	{
    text: 'Consider using Redux',
    completed: true,
  }, 
	{
    text: 'Keep all state in a single tree',
    completed: false
  }]
}
*/
  • 위의 코드를 그림으로 표현하면 아래와 같다.

2. 상태는 읽기 전용이다.

  • 상태 변화시키는 방법: 액션 객체를 전달.
    • 액션 객체: 무슨 일이 벌어지는 지 나타냄
    • 액션은 그저 평범한 객체 ⇒ 어플리케이션 페이로드 정보를 스토어에 전달
  • 모든 상태 변화는 중앙에서 관리
  • 모든 액션은 엄격한 순서에 의해 실행 ⇒ 신경써서 관리해야할 미묘한 경쟁 상태는 없음

따라서 기록을 남길 수도 시리얼라이즈(직렬화)할 수 있으며, 저장할 수 있고, 이후에 테스트나 디버깅을 위해서 재현하는 것도 가능.

//store: 상태관리하는 유일한 곳

//dispatch: 액션 객체들을 전달해준다 => 얘 통해서 액션 객체를 스토어로.

store.dispatch({
  type: 'COMPLETE_TODO', 
  index: 1 
})

store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})

3. 변화는 순수 함수로 작성되어야 한다.

액션에 의해 상태 트리가 어떻게 변화하는 지를 지정하기 위해 순수 리듀서를 작성해야한다.

  • 리듀서: 이전 상태와 액션을 받아 다음 상태를 반환하는 순수 함수이다.
    • 현재 상태와 액션을 이용해 다음 상태를 만든다.
    • 이전 상태를 변경하는 대신 새로운 상태 객체(State)를 생성해서 반환해야한다.

처음엔 하나의 리듀서로 충분 BUT 애플리케이션이 커지면서 상태 트리의 특정 부분을 조작하는 더 작은 리듀서들로 나누어 주는 것도 고려해야한다.

  • 리듀서는 함수 ⇒ 호출되는 순서를 정하거나 추가적인 데이터를 넘길 수도 있다.
  • 일반적인 재사용 가능한 리듀서를 작성하는 것도 가능.
function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return [
        ...state.slice(0, action.index),
        Object.assign({}, state[action.index], {
          completed: true
        }),
        ...state.slice(action.index + 1)
      ]
    default:
      return state
  }
}

import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)



Written with StackEdit.

0개의 댓글