React와 Redux (2)

yeong·2022년 6월 17일
0

react

목록 보기
2/4
post-thumbnail

상태를 읽어오기

이제 컴포넌트에서 저장소를 구독하고 데이터를 가져올 차례이다.
사실 redux만 사용한다면 구독을 위해서는 subscribe라는 함수를 사용한다.

예시로 구독자 함수를 만들고 해당 구독자를 연결해보자.

const subscriber = () => {
  let latestState = store.getState();
	console.log("receive new State !", latestState);
};

store.subscribe(subscriber);

위와 같이 코드를 작성하면 redux는 subsciber라는 구독자 함수를 인식하게되고 저장소가 변경되었을때 해당 함수를 트리거한다.
그리고 구독자함수 내에서 getState() 메서드로 최신 상태를 전달 받을 수 있다.

그러나 우리는 react-redux를 사용할 것이기때문에 위와같은 로직을 사용할일이 드물다.
subscribe()와 getState() 대신 react-redux가 제공하는 useSelect()훅을 사용할 수 있다.

useSelector 사용하기

import {useSelctor} from 'react-redux'

const status = useSelector((state) => state.status.status);

useSelector를 사용하면 자동으로 해당 컴포넌트가 redux store에 구독등록?이 된다. 따라서 store가 업데이트 되면 해당 컴포넌트가 자동으로 재실행된다. 또한 구독중인 store에서 최신상태값을 조회해올 수 있다. store.getState()와 동일한 기능을 하며 useSelector의 인수로 넘기는 콜백함수에 현재 store의 상태값이 매핑되고 그 상태값에서 원하는 속성을 꺼내기만 하면된다. 또한 컴포넌트가 unmount될때 구독은 자동으로 해지된다는것도 기억하자.

주의할것은 현재 reducer를 combineReducer로 결합했기때문에 특정 reducer에 속하는 상태값을 꺼내기 위해서는 combineReducer에 지정된 속성명을 거쳐야한다는 것이다. 위 코드에서 첫번째 status 속성이 그 역할을 한다.

useSelector를 사용할때 명심할 것은 가져오는 state값에 따라 렌더링여부가 결정된다는 것이다.
우리는 현재 state.status.status만을 가져오고 있으므로 state.status.status가 변경되었을때만 해당 컴포넌트가 재평가된다.
만약 state.status.error 가 변경되었다면 해당 컴포넌트는 재평가되지 않는다.

(state)=>({state : state.status.status });

와 같이 가져오려는 state를 객체로 감싼다면 react-redux는 객체안을 읽지못하고, 결국 가져오려는 값이 무엇인지 몰라 무조건 컴포넌트를 재렌더링 해버린다. 만약 state에서 두개이상의 상태값을 조회할때 하나의 상태값만 변경되는 케이스가 빈번하다면 객체타입을 피하는것이 좋을 것이다.

대신 useSelector을 여러번 사용하거나 react-redux의 shallowEqual 함수를 useSelector의 두번째 매개변수로 전달해주면 된다. 보다 자세한 내용은 useSelector최적화를 참고하는것을 추천한다.

상태 업데이트하기

마지막으로 상태 업데이트하기만 남았다.
상태를 업데이트하기 위해서는 컴포넌트내에서 action을 dispatch하면 된다.
진행순서는 다음과 같다.
1. 액션생성자 함수를 import 한다.
2. useDispatch() 훅으로 dispatch함수를 가져온다.
3. 액션생성자함수를 실행시켜 dispatch로 전달한다.

실제 코드로 예시를 본다면,

 const dispatch = useDispatch();

 const submitSearchFormHandler = async (e) => {
   e.preventDefault();
   dispatch(changeStatus("PENDING"));
	...
   dispatch(changeStatus(error?"ERROR" : "SUCCESS");
 };
 

api를 호출하면
useDispatch()함수로 가져온 dispatch 에 changeStatus라는 액션생성자함수를 호출해 생송헌 액션을 전달한다.
해당 액션생성자 함수는 상태의 status속성을 업데이트하는 액션을 생성한다.
이제 reducer로 해당 action이 전달될 것이며 전달한 action에 맞추어 state가 업데이트된다.
"PENDING"이라는 값을 전달했으므로 state.status는 PENDING 업데이트되며 해당 상태를 구독중인 모든 컴포넌트에 전달된다.
api호출을 종료하면 결과값에 따라 "ERROR", "SUCCESS"를 전달한다.
다시 state.status는 SUCCESS 혹은 ERROR로 업데이트되며 해당 상태를 구독중인 모든 컴포넌트에 전달된다.

정리하기

상태 업데이트까지 모두 완료되었다. 사실 redux에는 더 많은 기능이 있다. 또한 redux를 제대로 사용하기 위해서는 리덕스 미들웨어의 사용은 필수불가결하다고 할 수 있다.
앞으로 시간이 된다면 관련 내용도 블로그에 정리를 해볼 예정이다.
또한 redux를 편하게 사용하기 위한 toolkit도 존재한다! 사실 redux만 사용하기에는 reducer 코드가 너무 길어지거나, 기존 상태값을 수정하면 안된다는 규칙이 redux의 불편요소중 하나이다..
다만 toolkit을 사용한다면 기존 createRedux, reducer 정의 방식이 모두 달라지므로 다시 redux를 공부하는 기분을 낼 수 있다ㅎㅎ..
해당 내용도 나중에 기회가 되면 한번 정리해보고 싶다.

ref
React 완벽 가이드 with Redux, Next.js, TypeScript
벨로퍼트와 함께하는 모던 리액트

profile
안녕하세요!

0개의 댓글