service에서 리렌더링을 발생시킬 순 없는 건가요?

Sheryl Yun·2023년 5월 13일
0
post-thumbnail

service - context - component(view)로 나뉜 Auth/Todo 실습 코드를 복습하다가
로그인 여부에 따라 뷰를 업데이트하도록 개선할 때
꼭 새로고침을 해야 새로운 뷰가 반영되는 이슈가 발생했다.

리액트가 state 변경을 인지하게 하는 것을 제일 첫 단계인 service에서 하려고
한참(몇 시간)을 고민하다가 결국 커뮤니티의 도움으로 (코스에 참여하면 가장 좋은 점)
state 변경을 통한 리렌더링은 service의 역할이 아니다는 걸 알게 되었다.


👱‍♂️ 멘토님의 답변:

  • AuthService 클래스에서 setState를 해주고 있지만 이를 컴포넌트로 마운트하지 않아서 AuthService와 자식 컴포넌트가 리렌더링 되지 않는 것

    • service의 변동은 컴포넌트 리마운트되는 것에 영향을 주지 않는다는 뜻으로 해석
  • Provider에서 state.isLogin을 참조하고 있긴 하지만 이는 Provider의 state가 아니기에 변경된다고 리렌더링이 되지는 않는다

    • state가 Provider 내부의 것이 아니라, 외부에서 넘어온 것이기 때문에 Provider에서는 state의 변경을 감지할 수 없음 = 컴포넌트 리렌더링 안 됨
  • AuthService에서 state의 처리까지 담당하는 것은 권장하지 않는다. AuthService의 목적은 Auth에 관련된 기능들을 관리하는 것이지, React의 state까지 함께 처리하게 되면 AuthService에서 너무 많은 역할을 하게 되기 때문이다.

    • service는 말 그대로 '로직'을 관리할 뿐 state 관리와는 관계가 없어서 state 관리 로직까지 두게 되면 관심사 분리 원칙에 어긋난다

이렇게 이해를 했다. 음.. 명확하게 service에 state 코드를 두면 안 되는구나 😂


처음에 이걸 고민했던 이유가

실습 코드 service가 클래스형으로 되어 있는데 '예전에 함수형 없었을 때는 클래스형으로 짰을 테니까 클래스형 안에서도 뭔가 리렌더링과 관련한 state 관리가 가능하겠지?' 라고 생각해서 시작했는데

애초부터 틀린 접근 방법이었다 ^_^


어제 공부한 MVC 패턴 중에는 service랑 context가 어디에 해당하려나 생각해봤는데

현재 실습 코드에서 api를 호출하는 핵심 로직은 service에 있고
이걸 받아서 그대로 또는 반환값을 state로 관리해서 view에 주입하는 역할이 context인데

매칭을 해보려 하니 아직 controller를 잘 이해하고 있지 못한 것 같다 ^-ㅠ


코드는 이슈 논의 과정 중 하닮님이 예시를 들어주신 방식으로 수정하기로 했다.

bind, call, apply는 너무 오랜만에 보는 거라 적응이 안 됐는데 설명을 들으니 다시 생각났다.

bind는 이런 식으로

 const signin = authService.signin.bind(authService);

call은 이런 식으로 사용한다

  const signin = (email, password) => {
    authService.signin.call(authService, email, password);
    setIsLogin(true);
  };

책에서 봤던 예시 코드보다 실제 적용된 코드가 훨씬 이해하기 편했던 케이스 🙌

bind는 실행은 안 해줘서 그냥 넘기는(연결짓는) 역할만,
call과 apply는 실행까지 할 수 있어서
함수 안에서 실행하는 역할까지 담당 - 이렇게 이해했다.

멘토님 추가 답변을 통해
call과 apply의 차이는 call은 인수를 넘길 때 컴마(,)로 넘기고
apply는 배열([ ])로 넘긴다는 것도 기억났다 👍

profile
데이터 분석가 준비 중입니다 (티스토리에 기록: https://cherylog.tistory.com/)

0개의 댓글