강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

popo님의 프로필 이미지
popo

작성한 질문수

한 입 크기로 잘라먹는 실전 프로젝트 - SNS 편

(3.2) Zustand 기본 사용법 1

Zustand의 get/set 메서드 관련 질문 드립니다.

작성

·

30

·

수정됨

0

안녕하세요! 강의 잘 듣고 있습니다.

(3.2) Zustand 기본 사용법 1 강의의 9분 21초경에서 궁금한 점이 생겨 질문드립니다.

 

강의에서 get 메서드는 store(객체) 전체를 반환한다고 설명하셨습니다.
그리고 set 메서드는 인자로 전달된 객체의 프로퍼티만을 갱신한다고 하셨는데요.

그런데 아래 코드처럼 보면,
set 내부에서는 따로 get()을 호출하지 않아도 count 값을 바로 참조해 업데이트하고 있습니다.

 

increase: () => {
  const count = get().count;     // 여기서 store의 count 프로퍼티를 가져온다
  set({ count: count + 1 });     // 그런데 여기서는 count를 직접 사용할 수 있다?
}

 

제가 이해하기로는 store의 값을 변경하기 위해 프로퍼티를 참조할 때에도(여기서는 count:) 먼저 get()으로 현재 store의 참조를 얻은 뒤 수정해야 할 것 같은데,
set({ count: count + 1 })처럼 직접 count를 갱신할 수 있는 이유가 궁금합니다.

즉, set은 내부적으로 get()을 다시 호출해서 현재 store 상태를 알고 있는 건가요?
아니면 set이 store 객체의 참조를 이미 가지고 있어서 가능한 건가요?

답변 2

0

이정환 Winterlood님의 프로필 이미지
이정환 Winterlood
지식공유자

안녕하세요 이정환입니다.

우선 set({ count: count + 1 }); 문에서 set 메서드에게 인수로 전달되는 {count: count + 1}은 단순한 객체 리터럴 입니다.

이 라인 위에서 get() 메서드를 통해 count 변수에 현재 상태값을 할당해두었기 때문에, 이후에는 count를 일반 변수처럼 사용할 수 있는 것이죠.

즉, 이 시점에서 count는 더 이상 상태와 연결된 값이 아니라 단순한 숫자값(예: 3, 4, 5 등)입니다. 이 값을 바탕으로 count + 1을 계산한 후, 다시 객체 형태로 만들어 set에 전달하고 있는 겁니다.

 

앗! 그런데 혹시 질문의 취지가 “set 메서드 내에서 어떻게 정확히 count 프로퍼티를 변경할 수 있는지 알고 있느냐” 라는 걸까요?

만약 그렇다면 이는 combine 미들웨어의 기능이라고 이해하시면 좋을 것 같습니다.

우선 Zustand에서 상태를 업데이트할 때 사용하는 set() 함수는 전달된 객체를 현재 상태와 얕게 병합(shallow merge)합니다. 이때 주의할 점은, 기본적으로는 어떤 프로퍼티든 넣을 수 있다는 것입니다.

아래의 예제 코드를 살펴보시면 combine 미들웨어를 사용하지 않았을 때에는 set 메서드 내에서 구체적으로 어떤 프로퍼티들을 수정할 수 있는지 알지 못하기에 인수로 {a : 1} 과 같은 값을 전달해도 아무런 오류가 발생하지 않게 됩니다.

image.png

 

반면 아래처럼 combine 미들웨어를 사용하면 상황이 달라집니다. 아래의 예제 코드를 살펴보시면, 이번엔 combine 미들웨어를 사용했기 때문에 초기 상태가 명확하게 정의되고 타입이 고정됩니다. 이 상태에서 정의되지 않은 프로퍼티를 set()으로 전달하면 TypeScript 환경에서는 바로 오류를 발생시켜 줍니다. 즉, 상태 설계가 더 엄격해지고, 실수도 줄일 수 있게 되는 것이죠.

image.png

 

0

변수이름때문에 오해가 있는걸까요
increase: () => {

const num = get().count; // 현재 store의 count 값 가져오기.. 객체를 가져와서 그 객체의 count라는 property의 값을 꺼내서 num에 저장

set({ count: num + 1 }); // num 를 1 증가시켜 객체의 property중 하나인 count값을 업데이트 함

}
이렇게 하면 이해가 쉬울까요..
이거도 가능...(내부적으로 상태를알고있음)
increase: () => set((state) => ({ count: state.count + 1 })) 저도 강의듣고 있어요

popo님의 프로필 이미지
popo
질문자

변수라는 점은 이해하고 있습니다.


다만 set 메서드로 상태를 업데이트할 때, count:는 store의 프로퍼티를 가리키는데,
그 직후에는 get()으로 가져온 값을 변수로 선언해 count + 1 형태로 바로 사용하는 부분이 있습니다.

 

이 과정에서 별도의 store 참조 없이 프로퍼티(count)에 직접 접근이 가능한 이유가 궁금했습니다. (값의 조작은 store를 참조해와서 해야하는데, 어떻게 프로퍼티에는 바로 접근이 가능한지?)

조금 찾아보니, 이 동작이 useState처럼 클로저와 연관있는 거 같아요

popo님의 프로필 이미지
popo

작성한 질문수

질문하기