32일차 쉽게 다시 보는 리덕스

seul-bean·2023년 8월 15일
0

Note

목록 보기
2/3

🍎 리덕스의 구성요소

🌳 Store

모든 전역 State들을 관리하는 단 하나의 상태 저장소(→단 하나의 객체)

Store: {todos, auth}

store 내부의 리듀서들로부터 각각 최신 상태를 갖는다.

🌳 Reducer

state 변경 함수

  • 매개변수로 기존상태와 액션객체를 받음
  • 상태 변경 후 최신 상태를 Store에 제공 (리턴)

🌳 Action

{type, payload} 형태의 객체

  • 리듀서 함수에게 전달되는 인자
  • 리듀서에게 요구할 상태변경 작업에 대한 정의를 나타내는 객체 (상태변경 요청서)
  • type은 필수 속성. payload는 선택 속성

🌳 Dispatch

액션 객체를 인자로 받아 리듀서를 호출 시키는 함수

  • dispatch(액션객체)가 실행되면 리듀서 함수의 매개변수로 action 객체를 전달하며 호출

🍎 리덕스를 왜 써야 하나요?

  • props drilling으로 인한 불편함을 해소
  • 상태관리에 대한 유지보수성이 좋아짐. (코드베이스 규모가 커질수록 Good)
  • 디버깅이 쉬어짐. (redux dev tools) - 단순 전역 상태관리를 넘어 추가적인 옵션 기능 제공

🍎 전역 상태관리는 context API로도 되는데, 왜 리덕스를 써야 하나요?

관리해야할 State 수가 적은 편이면 context API만으로도 충분
확장성, 유지보수성까지 고려해야 한다면 리덕스와 같은 전역 상태 라이브러리를 적용하는 것이 현명한 선택


🍎 리덕스는 어떻게 동작하나요?

  1. 초기 상태 받기: 페이지 랜딩 시 useSelector를 통해 store에서 initialState를 받아 UI를 렌더링한다.
  2. 상태 변경 요청: 사용자 이벤트 발생 시 상태변경을 위해 dispatch(action)로 Store 내 각 리듀서들에게 action 전달하며 실행시킨다.
    (todos 리듀서 호출만을 의도했어도 auth 리듀서도 함께 호출된다. → action.type이 중복되면 안되는 이유!)
  3. 상태 변경 처리: 기존 State는 store부터, action 객체는 dispatch를 통해 매개변수로 받아서 리듀서 함수를 실행하여 action.type에 따라 상태 변경 처리 후 store에 변경된 최신 상태를 제공한다.
  4. 신규 상태 받기: useSelector를 통해 store의 특정 상태를 구독중인 현재 페이지 컴포넌트(view)는 상태 변경 알림을 받고 리렌더링한다.

상태 가져오기 (컴포넌트 자체 → form store)

상태 변경 요청하기(컴포넌트 자체 → to reducer)

const dispatch = useDispatch();
const deleteTodo=(id)=>{
	// 단순히 리듀서에게 상태 변경 요청만하는 패턴. 상태변경 로직은 리듀서 안에서 기술
    dispatch({type: "todos/DELETE_TODO", payload:id}) // → 리듀서 실행
    //dispatch(deleteTodo(id)) // 액션생성자 함수 적용 (휴먼에러 방지)
}

🍎 서로 다른 리듀서 모듈끼리 액션 타입이 중복되도 되나요?

dispatch({type:"ADD_TODO"})라고 하면 액션 객체는 store로 전달되서 모든 리듀서들에게 전달된다. 만약 action type이 todos 리듀서와 auth 리듀서 안에 각각 들어있다면 두 리듀서 함수가 모두 실행되어 예상치 못한 버그를 가질 수 있다!

// 리듀서명 / 액션명의 조함으로 혹여나 중복이 발생하지 않도록 한다.
// modules/todos.js
const ADD_TODO="todos/ADD_TODO";
// modules/auth.js
const ADD_TODO="auth/ADD_TODO";

🍎 Store 자체를 구독하는 건 지양해야 함.

// ❌ 불필요하게 리렌더링이 발생할 수 있음.
const store = useSelector(state => state);
const todos = store.todos;

// ⭕ Good!!
const todos = useSelector(state => state.todos);
profile
안녕하세요 성장하는 새싹 프론트엔드 개발자 입니다🌱

0개의 댓글