TSyringe
학습 키워드
TSyringe
의존성 주입(Dependency Injection)
reflect-metadata
sington (싱글톤)
TSyringe
: TypeScript용 DI 라이브러리
프론트엔드에서 DI를 언제 쓰는가?를 살펴보면 External Store를 관리할 때 사용한다. TSyringe를 잘 사용하면 전역처럼 사용이 가능하다.
\
전역처럼 사용 가능하다는 것이 무엇을 의미할까? 👉🏻 TSyringe는 @singleton으로 이뤄져 있다. 즉, 하나의 인스턴스만 생성할 수 있기 때문에 어느 곳에서 값을 참조해도 같은 값을 확인할 수 있다.
\
reflect-metadata
Reflect API를 위한 폴리필을 추가할 때 사용한다.
reflect-metadata를 사용할 수도 있고 공식 문서에서는 core-js, reflection과 같은 useage도 제공
\
✅ TSyringe 사용방법
store를 만든다.
만든 store를 app.tsx에서 사용
tsryinge는 container를 제공한다.

import “reflect-metadata” 를 어디에 써줘야할까?
👉🏻 모든 프로그램이 시작하는 곳에 써줘야한다. main.tsx
테스트 파일은 시작하는 곳이 없는데 테스트 파일에서는 어디에 명시해줘야할까?
👉🏻 jest.config.js 에서 확인해보면 '<rootDir>/src/setupTests.ts', 시작점을 설정해줬었다.
\
다시 실행시켜보면 다른 오류 발생

타입스크립트에서도 데코레이터를 쓸 수 있도록 만들어줘야한다. 👉🏻 tsconfig에서 주석을 해제해주면 된다.
데코레이터는 선언적 구문을 통해 클래스가 정의될 때 클래스와 그 멤버를 보강하는 기능을 추가함
\
\
App.tsx
Store.ts
Counter.tsx
CounterControl.tsx
\
만약 Counter 컴포넌트를 여러 개 만든다면?

값을 덮어쓰기 때문에 마지막 컴포넌트만 값이 출력된다.
하나의 값을 여러 개의 컴포넌트에서 렌더링하고 싶다면?
Couter.tsx
사실은 store.forceUpdates.add(forceUpdate); 코드도 렌더링이 될 때마다 add 하면 안되기 때문에 useEffect를 사용해야한다.
\
Refactoring 1
캡슐화를 하기 위해 리팩토링을 해보면,
Store.ts
CountControl.tsx
테스트 코드 작성
이 때 발생하는 오류
TestingLibraryElementError: Found multiple elements with the text: Count: 1
👉🏻 screen.getByText('Count: 1') 결과는 한 개만 나와야하는데 두 개가 나왔기 때문에
\
context를 나눠서 테스트를 실행시켜보면?

2가 나올 것이라고 예상했지만 실제 결과는 3이 나오는 것을 볼 수 있다.
테스트 코드를 작성할 때는 각각이 독립적이어야 한다. 문제는 전역의 상태를 쓰고 있기 때문에 독립적이지 않다.
이를 해결하기 위해선 실행시킬 때 매번 초기화를 시켜주면 된다.
\
Refactoring 2
상태가 변경되면 리렌더링을 다시하는 로직을 커스텀 훅으로 분리시켜보자.
useCounterStore.tsx
커스텀훅으로 분리했을 때의 장점은 store만 가져와서 사용하면 된다는 것이다.
handleClickIncrease, handleClickDecrease 내부 로직도 캡슐화를 시킬 수 있다.
Last updated