NgRx 툴킷 v21
Source: Dev.to
위에 제공된 소스 링크만으로는 번역할 본문이 포함되어 있지 않습니다. 번역을 원하는 텍스트를 그대로 복사해서 알려주시면, 요청하신 대로 한국어로 번역해 드리겠습니다.
툴킷이 제공하는 것
NgRx Toolkit은 Angular 애플리케이션에서 일반적으로 필요한 다양한 확장 기능을 포함하고 있습니다. 아래는 핵심 기능의 간략한 연혁입니다:
| Feature | Description |
|---|---|
withDevtools() | 어떤 SignalStore(Redux 기반이든 아니든)든 Redux DevTools를 사용할 수 있게 합니다. withDevtools('storeName')를 추가하여 스토어 상태를 시각화합니다. |
@ngrx/signals/event & withFeature | 현재 @ngrx/signals 코어의 일부이며, 원래는 Toolkit에서 인큐베이팅되었습니다. |
withStorageSync() | 상태를 Web Storage(localStorage / sessionStorage)와 IndexedDB(비동기 전략을 통해)와 동기화합니다. withStorageSync('storeName')를 사용합니다. IndexedDB 지원은 지난해 커뮤니티 기여(#134)에 의해 추가되었습니다(GitHub 사용자 mzkmnk). |
| Other extensions | 전체 목록은 문서에서 확인하세요. |
v20 마이너 기능: withResource, withEntityResources, & Mutations
withResource() / withEntityResources()
- **
withResource**는 Angular의 Resource API를 스토어와 연결하여 스토어가 비동기 데이터를 관리하도록 합니다(예: API에서 로드). 이름이 없는 변형과 이름이 있는 변형을 모두 지원합니다. - **
withEntityResources**는@ngrx/signals/entities로 구축된 스토어에 동일한 기능을 제공합니다.
Mutations API
Mutations API는 일반적인 REST 경험의 “쓰기” 측면을 추가합니다. 제공 내용:
- 독립 함수:
httpMutation,rxMutation - 기능 래퍼:
withMutations
디자인은 Angular Query와 Marko Stanimirović가 제안한 mutations API에서 영감을 받았으며, 내부 논의에는 Alex Rickabaugh가 참여했습니다.
import {
httpMutation,
rxMutation,
withMutations,
withResource,
withEntityResources,
} from '@angular-architects/ngrx-toolkit';
export const UserStore = signalStore(
withState({ userId: undefined as number | undefined }),
// Async data handling via Angular Resource API
withResource(({ userId }) => ({
detail: httpResource(() =>
userId === undefined ? undefined : `/user/${userId}`
),
})),
// Mutations (save, post, etc.)
withMutations((store, userService = inject(UserService)) => ({
saveUserDetail: rxMutation({
operation: (params: Params) =>
userService.saveUserDetail(store.counter(), params.value),
onSuccess: (result) => {
// …
},
onError: (error) => {
// …
},
}),
saveToServer: httpMutation({
request: () => ({
url: `https://httpbin.org/post`,
method: 'POST',
body: { counter: store.counter() },
}),
parse: (response) => response as UserResponse,
onSuccess: (result) => {
// …
},
onError: (error) => {
// …
},
}),
})),
// Entity‑level resources
withEntityResources(() =>
resource({
loader: () => Promise.resolve([] as User[]),
defaultValue: [],
})
)
);
v21 – 새로운 기능
주요 추가 사항
withResource()및withEntityResources()에 대한 향상된 오류 처리- Redux DevTools에 이벤트 통합
clearUndoRedo도입 (store.clearStack대체)
업그레이드된 withResource() / withEntityResources() 오류 처리
Angular 리소스는 교착 상태에 빠질 수 있습니다. 리소스가 오류 상태에 들어가면 params의 시그널을 업데이트하면서 patchState가 호출되고, 이 과정에서 다시 상태 값을 접근하게 되어 또 다른 오류가 발생할 가능성이 있습니다.
Toolkit은 이제 withResource()에서 오류를 처리하기 위한 여러 전략을 제공합니다:
type ErrorHandlingStrategy =
| 'throw' // 원본 오류를 다시 발생시킴 (기본값)
| 'ignore' // 오류를 조용히 무시하고 이전 상태를 유지
| 'fallback' // 사용자 제공 함수로 대체 값을 제공
| 'custom' // 사용자 정의 오류 처리 콜백을 실행
리소스를 구성할 때 원하는 전략을 선택합니다:
withResource(
({ userId }) => ({
detail: httpResource(() =>
userId === undefined ? undefined : `/user/${userId}`
),
}),
{
errorHandling: 'fallback',
fallbackValue: () => ({ name: 'Anonymous', id: 0 })
}
);
이벤트 통합을 통한 DevTools
withDevtools()가 이제 스토어에서 발생한 사용자 정의 이벤트를 캡처하여 Redux DevTools UI에서 상태 변화와 함께 확인할 수 있게 되었습니다.
clearUndoRedo
이전 store.clearStack() 메서드는 clearUndoRedo()로 대체되었습니다. 이 메서드는 undo와 redo 히스토리를 모두 삭제한다는 목적을 보다 명확하게 전달합니다.
참조
- 문서: (link to official docs)
- IndexedDB 기여: (by mzkmnk)
- Angular Query (뮤테이션 영감): (link)
- Marko Stanimirović의 뮤테이션 제안: (link)
오류‑처리 전략
errorHandling = 'native' | 'undefined value' | 'previous value';
withResource(
(store) => {
const resolver = inject(AddressResolver);
return {
address: resource({
params: store.id,
loader: ({ params: id }) => resolver.resolve(id),
}),
};
},
// Other values: 'native' and 'previous value'
{ errorHandling: 'undefined value' } // default if not specified
);
옵션
| Value | Description |
|---|---|
'undefined value' (default) | 오류가 발생하면 리소스의 값이 undefined가 됩니다. |
'previous value' | 리소스가 이전에 값을 가지고 있었다면 그 값을 반환하고, 그렇지 않으면 오류가 발생합니다. |
'native' | 별도의 처리를 하지 않으며 기본 오류 동작이 적용됩니다. |
withEntityResources()의 경우 전략은 'undefined value'입니다.
내부적으로 'previous value'와 'undefined value'는 값을 프록시합니다. 자세한 설명은 JSDoc for the error‑handling strategy 를 참고하세요.
DevTools에 이벤트 통합
여기에 약간의 아이러니가 있습니다. NgRx Toolkit은 공식 플러그인이 나오기 전에 Signal Store에 이벤트를 도입했으며, Redux와 함께 혹은 없이 Redux DevTools 통합도 제공합니다. 하지만 현재 공식화된 NgRx 이벤트 기능은 Toolkit의 withDevtools와 직접 매핑되지 않았습니다.
NgRx Toolkit v21에서는 withTrackedReducer()를 도입해 이 문제를 해결했습니다. 이는 Redux DevTools에서 리듀서 기반 상태 변화를 추적하는 대안적인 방법입니다.
사용 방법
-
withReducer사용을withTrackedReducer로 교체합니다.
(네이티브withReducer지원은 계획 중이지만@ngrx/signals의 상위 변경이 필요합니다.) -
withDevtools안에withGlitchTracking을 지정합니다.
withTrackedReducer를 DevTools와 glitch tracking 없이 사용하면 런타임 오류가 발생합니다.
import {
withTrackedReducer,
withGlitchTracking,
withDevtools,
} from '@angular-architects/ngrx-toolkit';
export const bookEvents = eventGroup({
source: 'Book Store',
events: {
loadBooks: type(),
},
});
const Store = signalStore(
{ providedIn: 'root' },
withDevtools('book-store-events', withGlitchTracking()),
withState({
books: [] as Book[],
}),
withTrackedReducer(
// `[Book Store] loadBooks`가 DevTools에 표시됩니다
on(bookEvents.loadBooks, () => ({
books: mockBooks,
}))
),
withHooks({
onInit() {
injectDispatch(bookEvents).loadBooks();
},
})
);
clearUndoRedo – store.clearStack 대체
clearStack은 deprecated(사용 중단)되었습니다.- 대신 새로운 독립 함수 **
clearUndoRedo**를 사용하세요.
clearUndoRedo는 기본적으로 soft reset을 수행하며(state를 null로 설정하지 않음) 옵션을 통해 hard reset을 요청할 수 있습니다:
clearUndoRedo(store, { lastRecord: null });
Gregor Woiwode가 구현했습니다. NgRx Toolkit v19.5.0 및 v20.7.0에 백포팅되었습니다.
ngrx-toolkit-openapi-gen
우리는 Murat Sari에게서 환상적인 크리스마스 선물을 받았습니다: 다음을 생성하는 OpenAPI 생성기입니다.
- ✅ NgRx Signal Store
- ✅ 리소스
- ✅ 뮤테이션
- ✅ Zod 스키마 기반 코드
생성된 코드는 정말 아름답습니다—코드 생성기에서 흔히 볼 수 없는 수준입니다.
- npm: (link)
- Documentation: (link)
Future Release Strategy for Compatible Angular Versions
Version 21 of the Toolkit took longer due to new features and fixes. NgRx v21 was compatible with later Toolkit v20 releases, but only with certain overrides. To smooth the experience, we released NgRx Toolkit v20.6.0, supporting both NgRx v20 and v21. The same applies to v20.7.0, which back‑ported several v21 features.
Going forward:
If obstacles arise for any upcoming major Toolkit release, we will publish a minor Toolkit version that is compatible with the next stable major NgRx release as soon as it’s ready for integration.
감사드립니다!
우리는 시간, 전문 지식, 토론 및 코드를 기여해 주신 모든 분들께 감사드립니다. 이 글의 하이라이트된 기여자들에게 특별히 감사드립니다:
여러분의 노력 덕분에 NgRx Toolkit 커뮤니티가 더욱 강해집니다. 🙏