신나고 깜찍한 Redux의 세계 (2)

dongha1992·2020년 12월 13일
0

redux

목록 보기
2/3
post-thumbnail

예제 친구와 함께 리덕스를 배워보자!

몸풀기

리덕스의 시작 플로우는 **스토어를 만든다 -> state가 생성된다 -> 리듀서를 만들어서 state에 주입한다 **

npm에 redux를 추가하면 reducer란 객체가 생긴다.

reducer 함수를 만들고 첫 번째 인자로 state, 두 번째 인자로 action을 받는다. state가 undefined라는 건 초기 state의 값이므로 초기 값을 리턴하게 한다.

그리고 store를 생성하는데 createStore에 reducer의 리턴값을 주입한다.
state는 store에 getState 매서드로 가져온다. state를 확인하면

이렇게 지정값이 나온다.

store에 dispatch를 호출하면 reducer함수를 호출한다. 이전의 state값과 액션의 값을 인자로 주는데 dispatch 안에 있는 친구들이 액션이다.

나는 물성파이므로 직접 확인해야 한다. create 버튼을 클릭하면 이렇게 초기 state와 액션 값이 reducer안에 들어온다!

reducer는 최초 한 번 무조건 실행되기 된다!

시작

reducer에 state값으로 contents를 주입한다.

list에 있는 내용이 클릭될 때마다 dispatch가 실행되게 설정하고

reducer에서 action이 SELECT일 때를 정의해서 새로운 state를 반환한다.

first를 클릭할 때 각각 action, state, newState

second를 클릭할 때

제대로 들어온 것을 확인했다!! 신난다!!

state 변경

list를 클릭했을 때 클릭한 list를 렌더해야 한다. _selected_content라는 변수에 selected_id와 같은 값을 정하고 그것을 setSelectedContent useState에 넣는다.

일단 reducer의 selected_id를 하드코딩으로 1로 정하면

요렇게 무엇을 클릭하든 selected_id가 1인 list를 렌더한다.

이 플로우가 너무 헷갈려!!!!!!!!!!

실습

카트 페이지에서 아이템을 추가 하면 장바구니에서 취소가 가능하다.

이제 문제는 카트 페이지의 상태가 최상위인 routes에서 관리되고 있다는 것!

즉, 상태를 업데이트 하면 모든 컴포넌트들이 업데이트 된다. 카트 아이템을 하나 지워도 3개의 컴포넌트가 렌더되는 비효율적인 나쁜 친구들을 리덕스로 관리해야 한다.

리덕스 적용

네비게이터에 있는 장바구니 개수는 전역 store에서 관리

장바구니 담기를 클릭하면 전역 store에 있는 배열에 추가

전역 store에 있는 배열 list! 취소하면 filter로 업데이트하면서 관리하면 된다.

초기세팅

리덕스 폴더를 만들어야 한다.

요렇게 폴더를 세팅한다.

액션 생성

두 가지 액션이 있다. 카트 추가와 카트 제거

addCart 함수가 실행되면 타입과 payload를 담은 객체가 리턴된다.

deleteCart의 경우 필터된 items를 받아서 새로 렌더하기 때문에 items를 받는다.

리듀서

리듀서는 action 함수가 생성한 action 객체를 dispatch 했을 때 들어오는 것이다! reducer는 보통 switch로 한다.

아무것도 없을 땐 기존의 state를 리턴한다.

가장 중요한 건 불변성을 유지해야 하기 때문에 spread로 기존의 것에 추가하는 방식으로 add한다. delete의 경우 장바구니가 통으로 주입되니까 payload만 spread해준다!!!!!!!!

state의 초기값까지 정해주면 완료

reducer들이 여러 개 있을 수 있으니까 root reducer가 필요하다. 그곳은 같은 폴더에 index.js에서 combine reducer라는 함수를 통해서!

요렇게 combineReducers를 통해 cartReducer를 합칠 수 있다.

스토어 생성

이제 index.js에 전역 스토어를 생성하고 root reducer와 연결해야 한다. 이제 store를 모든 컴포넌트들과 연결하기 위해 provier가 필요하다.

요렇게 provider로 감싸고 store를 주면 된다. 이제
필요한 컴포넌트에서 useSeletoruseDispatch로 필요한 상태를 업데이트하고 가져오면 된다!

장바구니 아이템 개수 세기

itemCount라는 props를 받는데 routes에서 전체 배열의 길이다. 이제 store에 연결하자! 필요한 것은 useSeletor다.

원래 props로 받던 itemCount를 지우고 useSelector로 store를 가져온다. store를 찍어보면

이렇게 cartReducer에 초기 state값을 가져온다.

reducer는 스토어의 키 값처럼 생각해도 된다!

가져온 items 배열의 length를 렌더하면 되는데 문제는 카트에 추가해도 업데이트가 되지 않고 그저 초기값의 length만 보여준다! 이제 장바구니 담기를 눌르면 store에 담겨야 한다.

디스패치

나쁜 친구 디스패치 헷갈린다. 일단 필요한 것은 useDispatch다. dispatch는 store에 연결된 함수다. dispatch는 액션 객체가 필요하다. 가져오자 액션 객체!

dispatch를 정의하고 onClick됐을 때 addCart 액션 함수에 item을 준다.

아이템을 클릭하면 dispatch에 의해 addCart 액션 함수가 스토어로 보내졌고 스토어 전에 reducer를 통해 타입에 의해 액션이 실행되고 업데이트 되는데 그 스토어와 연결된(바라보는) 컴포넌트는 상태가 업데이트 된다.

카트 업데이트 하기

cartList를 스토어로 교체해야 한다.

이렇게 selector로 접근하면 된다!!!

화면과 로직과 내 마음이 일치됐다.

장바구니 삭제를 통해 필터하기

필터된 결과를 스토어로 업데이트하면 된다!

이제부터 헷갈려서 죽을 거 같아

일단 selector로 cartItems를 스토어에서 가져온다. 그리고 dispatch로 업데이트 값을 스토어로 보내야 한다.

filter 함수에 dispatch 함수를 넣고 액션에 정의한 deleteCart를 주입한다! deleteCart의 인자로는 filter된 친구들이 필요해.

필터 업데이트도 성공!

출처 : 위코드 노션

profile
글과 코드와 사람에 관해 생각합니다.

1개의 댓글

comment-user-thumbnail
2020년 12월 13일

당신도 깜찍해..

답글 달기