๐ Angular์์ NgRx๋ฅผ ์ฌ์ฉํ ์ํ ๊ด๋ฆฌ
๐ NgRx๋ฅผ ์ฌ์ฉํ์ฌ Angular ์์ฉ ํ๋ก๊ทธ๋จ์ ์ํ๋ฅผ ์ฝ๊ฒ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์๊ณ , ์ฌ์ฉ์์ ๊ด๋ จ๋ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด Auth0์ SDK์ NgRx๋ฅผ ๊ฒฐํฉํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ค.
๊ฐ๋จํ ์๊ฐ
์์ฉ ํ๋ก๊ทธ๋จ์ ๊ตฌ์ถํ ๋ ์ํ ๊ด๋ฆฌ๋ ๊ด๊ฑด์ ์ธ ๊ตฌ์ฑ ์์์ด๋ค.์ฐ๋ฆฌ๋ ๊ฐ์ข ๋ฐฉ๋ฒ์ ํตํด ๊ฐ๋ ์์ฉ ํ๋ก๊ทธ๋จ์ ์ํ๋ฅผ ๊ด๋ฆฌํ ์ ์์ผ๋ฉฐ, ๋ชจ๋ ๋ฐฉ๋ฒ์ ์ฅ์ ๊ณผ ๋จ์ ์ ๊ฐ์ง๊ณ ์๋ค.
์ด ๋ธ๋ก๊ทธ์์๋ ์ํ ๊ด๋ฆฌ ์๋ฃจ์ ์ผ๋ก NgRx๋ฅผ ์ค์ ์ ์ผ๋ก ์๊ฐํฉ๋๋ค.NgRx๋ฅผ ์ฌ์ฉํ์ฌ Recipe Admin Dashboard ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ตฌ์ถํ์ฌ ์์ฉ ํ๋ก๊ทธ๋จ์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ฐ๊ตฌํ ๊ฒ์ ๋๋ค.Auth0 ๋ณดํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ NgRx์ ํจ๊ป ์์ ํ๋ ๋ฐฉ๋ฒ๋ ํ์ตํฉ๋๋ค.
Ngrx ์๊ฐ
NgRx์ Angular์์ ๋ฐ์์ ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ตฌ์ถํ๋ ๋ฐ ์ฌ์ฉ๋๋ ํ๋ ์์ํฌ์ ๋๋ค.NgRx์ ์๊ฐ์ Redux ๋ชจ๋ - ์์ฉ ํ๋ก๊ทธ๋จ์ ์ด๋ฒคํธ๋ฅผ ํต์ผํ๊ณ RxJS๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ฅผ ๋ด๋ณด๋ ๋๋ค.๋์ ๋ ๋ฒจ์์ NgRx๋ ๋จ์ผ ์ํ๋ฅผ ์ ์ฅํ๊ณ ๋์์ ์ฌ์ฉํ์ฌ ์ํ ๋ณํ๋ฅผ ๋ํ๋ธ๋ค.NgRx๋ ๋ง์ ์ฌ์ฉ์ ์ํธ ์์ฉ๊ณผ ์ฌ๋ฌ ๋ฐ์ดํฐ ์์ค๊ฐ ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ํฉํ ๋ณต์กํ ์ํ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
Ngrx์ ์๋ ๋ฐฉ์
NgRx๋ ์คํ ๋ฆฌ์ง, ์์ , ๋ณต์, ์ ํ๊ธฐ ๋ฐ ํจ๊ณผ ๋ฑ 5๊ฐ์ ์ฃผ์ ๊ตฌ์ฑ ์์๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
NgRx๋ ๋ชจ๋ ์ดํ๋ฆฌ์ผ์ด์ ๋ฐ์ดํฐ๊ฐ ๋์ผํ ๋ผ์ดํ ์ฌ์ดํด์ ๊ฑฐ์น๋ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ์คํธ๋ฆผ์ Redux ๊ฐ๋ ์ ์ฌ์ฉํฉ๋๋ค.์ด๋ฐ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ์ ์์ฉ ํ๋ก๊ทธ๋จ์ ์ํ๋ฅผ ๋์ฑ ์์ธกํ ์ ์๊ธฐ ๋๋ฌธ์ ์ดํดํ๊ธฐ ์ฝ๋ค.์ด ํ๋ฆ์ ์ํ ๊ด๋ฆฌ์ธต์๋ง ์ ์ฉ๋๋ฉฐ ํ์์ธต์ ๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ๊ณผ ํผ๋ํ ์ ์์ต๋๋ค.๋ค์ ๊ทธ๋ฆผ์ NgRx์ ์ํ ๊ด๋ฆฌ ๋ผ์ดํ ์ฌ์ดํด์ ๋ณด์ฌ์ค๋๋ค.
์์ ๊ณ
ํด๋ผ์ด์ธํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ๋ณผ ์ ์์ต๋๋ค.NgRx์ ์คํ ๋ฆฌ์ง๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ณ ์ ํ ์ง์ ์์ฒ์ด ๋ฉ๋๋ค.์ด๊ฒ์ ์์ฉ ํ๋ก๊ทธ๋จ์ ํ์ฌ ์ํ๋ฅผ ๋ฐ์ํฉ๋๋ค.
ํ๋
๋์์ ํ๋ก๊ทธ๋จ์์ ๋ฐ์ํ๋ ๋ ํนํ ์ด๋ฒคํธ๋ฅผ ํ์ํฉ๋๋ค.์ด๋ฌํ ์ด๋ฒคํธ์ ๋ฒ์๋ ์์ฉ ํ๋ก๊ทธ๋จ์ ์๋ช ์ฃผ๊ธฐ ์ด๋ฒคํธ, ์ฌ์ฉ์์ ์ํธ์์ฉ์์ ๋คํธ์ํฌ ์์ฒญ์ ์ด๋ฅด๊ธฐ๊น์ง์ด๋ค.์ ํ๋ฆฌ์ผ์ด์ ์ด NgRx์ ํต์ ํ๋ ๋ฐฉ๋ฒ์ ์๋ ค ์ฃผ๋ ์์ ์ ๋๋ค.
๊ฐ์๊ธฐ
ํ์๊ธฐ๋ ์ํ ๊ฐ์ ์ ํ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ ์ฑ ์์ง๋ค.reducer๋ ์ค์ผ์ค๋ง ์์ ์ ๋ฐ์ํ๊ณ ์์ ํจ์๋ฅผ ์คํํ์ฌ ์ ์ฅ์๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค.์๊ธฐ๋ฅ์ ์์ธก ๊ฐ๋ฅํ๊ณ ๋ถ์์ฉ์ด ์๋ ๊ธฐ๋ฅ์ด๋ค.๊ฐ์ ์ ๋ ฅ ์งํฉ์ ์ง์ ํ๋ฉด ์์ ํจ์๋ ํญ์ ๊ฐ์ ์ถ๋ ฅ ์งํฉ์ ๋๋๋ ค์ค๋๋ค.
์ ํ๊ธฐ
์ ํ๊ธฐ๋ ์์ ์์ ์ํ ์ธ์ ์ ๊ฐ์ ธ์ค๋ ์์ ํจ์์ ๋๋ค.์ ํ๊ธฐ๋ ํ๋ก๊ทธ๋จ์ด ์ํ ๋ณํ๋ฅผ ๊ฐ์ฒญํ๋ ๋ฐฉ์์ ๋๋ค.
์ํฅ
ํจ๊ณผ๋ ๊ฐ ๋์์ ๋ถ์์ฉ์ ์ฒ๋ฆฌํ๋ค.์ด๋ฌํ ๋ถ์์ฉ์ ์ด๋ค ์์ ์ด ์ค์ผ์ค๋ง๋ ๋ HTTP๋ฅผ ํตํด ์ธ๋ถ API์ ํต์ ํ๊ณ ๋ค๋ฅธ ์์ ์ ์ค์ผ์ค๋งํ์ฌ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ค๋ฅธ ๋ถ๋ถ์ ํฌํจํ๋ค.
์ ๊ฒฐ ์กฐ๊ฑด
Angular์๋ active LTS or maintenance LTS ๋ฒ์ ์ ๋ ธ๋๊ฐ ํ์ํฉ๋๋ค.js.๊ฐ๋ ์์ฉ๋ npm packages์ ๋ง์ ํน์ฑ๊ณผ ๊ธฐ๋ฅ์ ์์กดํ๋ค.npm ํจํค์ง๋ฅผ ๋ค์ด๋ก๋ํ๊ณ ์ค์นํ๋ ค๋ฉด npm ๋๋ yarn๊ณผ ๊ฐ์ npm ํจํค์ง ๊ด๋ฆฌ์๊ฐ ํ์ํฉ๋๋ค.
์ด ํ๋ก์ ํธ๋ ์๋ฒ ์ธก ๊ตฌ์ฑ ์์๊ฐ ์๋๋ฐ, ์คํ ์ ๋จ์ ์์ ๋ ๋ฐ๋์ ๋ณํ ์คํํด์ผ ํ๋ค.Api Express Typescript Menu repo์ ์ง์นจ์ ๋ฐ๋ฆ ๋๋ค.์ด blog post์์ Auth0์ ์ฌ์ฉํ์ฌ ์๋ฒ ์ฌ์ด๋๋ฅผ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ๋ด์ฉ์ ํ์ธํ ์ ์์ต๋๋ค.
์ด ์์ต์๋ Auth0์ NgRx์ ํจ๊ป ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ค์ ์ ์ผ๋ก ์ค๋ช ํฉ๋๋ค.๊ฐ๋ ์์ฉ ํ๋ก๊ทธ๋จ์ Auth0 ์ค์ ์ ๋ํ ์์ธํ ๋ด์ฉ์ README์ ์ง์นจ์ ๋ฐ๋ฅด๊ฑฐ๋ ์ด blog post์ ์ฐธ์กฐํ์ญ์์ค.
๋น ๋ฅธ ์์
NgRx ๊ด๋ จ ์น์ ์ ์ง์ํ๋ ๊ธฐ๋ณธ ๊ตฌ์กฐ์ ๊ตฌ์ฑ ์์๊ฐ ์๋ ํ๋ ์ ํ ์ด์ ํ๋ก๊ทธ๋จ์ ๋ง๋ค์์ต๋๋ค.
ํด๋ก ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณด์ฌ์ฃผ๊ณ starter ๋ถ๊ธฐ๋ฅผ ํ์ธํฉ๋๋ค.
git clone -b starter [email protected]:auth0-developer-hub/spa_angular_typescript_dashboard.git
ํด๋ก ์ฌ๊ตฌ๋งค ๊ณ์ฝ ํ spa_angular_typescript_dashboard
์ ํ์ฌ ๋๋ ํ ๋ฆฌ๋ก ์ค์ ํฉ๋๋ค.cd spa_angular_typescript_dashboard
์ค์น ํ๋ก์ ํธ์ ์ข
์ ํญ๋ชฉ:npm i
๋ก์ปฌ์์ ํ๋ก์ ํธ๋ฅผ ์คํํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ์ญ์์ค.npm run start
๊ฐ๋ฐ ๋๊ตฌ
Chrome์ด๋ Firefox์ฉ redux devtools ํ์ฅ์ ์ฌ์ฉํ์ฌ ์คํ ๋ฆฌ์ง์ ๊ด๋ จ๋ ์์ ์ ๋๋ฒ๊น ํ ์ ์์ต๋๋ค.
์ด ํ์ฅ์๋ฅผ NgRx์ ํจ๊ป ์ฌ์ฉํ๋ ค๋ฉด ํ๋ก์ ํธ์ NgRx์ devtools ์์กด ํญ๋ชฉ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.์ด ์์ ์
npm
๋๋ Angular CLI ๋ฅผ ์ฌ์ฉํ์ฌ ์ํํ ์ ์์ต๋๋ค.npm
์ฌ์ฉnpm install @ngrx/store-devtools --save
Angular CLI ์ฌ์ฉTo use the Angular CLI, you will need to have the CLI installed globally. Refer to instructions on the Angular docs for how to set this up.
ng add @ngrx/store-devtools@latest
StoreDevToolsModule
์์ AppModule
์ ๊ฐ์ ธ์ค๊ณ ํ๋ก์ ํธ ์๊ตฌ์ ๋ฐ๋ผ ์ค์ ํฉ๋๋ค.์ด ๊ฐ์ข์์ ๊ธฐ๋ณธ ์ค์ ์ ์ฌ์ฉํฉ๋๋ค.app.module.ts
์ ์ด๊ณ ๋ค์ ์ฝ๋๋ฅผ ์ถ๊ฐํ์ญ์์ค๐// src/app/app.module.ts
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http";
import { AuthHttpInterceptor, AuthModule } from "@auth0/auth0-angular";
// โจ New ๐
import { StoreDevtoolsModule } from "@ngrx/store-devtools";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { NavBarModule } from "./shared";
import { environment } from "src/environments/environment";
import { reducers, metaReducers } from "./core/state";
import { UserEffects } from "./core/state/user";
import { MenusEffects } from "./core/state/menus";
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
AuthModule.forRoot({
...environment.auth,
httpInterceptor: {
allowedList: [
`${environment.serverUrl}/api/menu/items`,
`${environment.serverUrl}/api/menu/items/*`,
],
},
}),
AppRoutingModule,
NavBarModule,
// โจ New ๐
StoreDevtoolsModule.instrument({
maxAge: 25,
logOnly: environment.production,
}),
],
declarations: [AppComponent],
bootstrap: [AppComponent],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthHttpInterceptor,
multi: true,
},
],
})
export class AppModule {}
If you used Angular's CLI to add NgRx devtools, this part might have been updated automatically.
์์ฉ ํ๋ก๊ทธ๋จ์ ์คํํ๊ณ Devtools ์ด๊ธฐ
์ด ์น์ ์ ์ ์ฐจ์ ๋ฐ๋ผ ํ๋ก๊ทธ๋จ์ ์คํํ๋ฉด ๋๊ตฌ ๋ชจ์์์ Redux Devtools๋ฅผ ํ์ฑํํ๋ ์ต์ ์ด ํ์๋ฉ๋๋ค.ํ์ฑํ๋๋ฉด ๋ค์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
You can learn more about these features from their official documentation.
NgRx ์ค์น
npm
๋๋ Angular CLI๋ฅผ ์ฌ์ฉํ์ฌ NgRx ์ข
์์ฑ์ ์ค์นํ ์ ์์ต๋๋ค.npm
์ฌ์ฉnpm install @ngrx/store --save
Angular CLI ์ฌ์ฉng add @ngrx/store@latest
๋๋ ์์ ์ ๋ถ์์ฉ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด NgRx์ ํจ๊ณผ๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ค.์ด๋ฐ ์์กด์ฑ์ ์ฒจ๊ฐํฉ์๋ค.npm
์ฌ์ฉnpm install @ngrx/effects --save
Angular CLI ์ฌ์ฉng add @ngrx/effects@latest
At the time this post was written, the latest NgRx store and effects version was
12.2.0
, which will be the version we will be using throughout the tutorial.
๊ฑด์ถํ๋ค
์ด ์์ฉ ํ๋ก๊ทธ๋จ์ ํต์ฌ์ ๊ด๋ฆฌ ๊ณ๊ธฐํ์ผ๋ก ๋ก๊ทธ์ธํ ์ฌ์ฉ์๊ฐ ๋ฉ๋ด ํญ๋ชฉ์ ์ถ๊ฐ, ํธ์ง, ์ญ์ ํ ์ ์๋ค.๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ ํด๋น ๊ถํ์ ๋ฐ๋ผ ๋ชจ๋ ์์ ๋๋ ํ์ ์ธํธ ์ค ํ๋๋ฅผ ์ํํฉ๋๋ค.์ํ ์ ๋ฐ์ดํธ์ ์ฌ์ฉ์/์๋ฒ ๊ด๋ จ ์ด๋ฒคํธ๋ฅผ ๊ด๋ฆฌํ๋ ค๋ฉด NgRx๋ฅผ ์ฌ์ฉํ์ญ์์ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํด ๋ ๊ฐ์ ์คํ ๋ฆฌ์ง๋ฅผ ์์ฑํฉ๋๋ค.
๋ฉ๋ด: ๋ฉ๋ด ๊ด๋ จ ๊ด๋ฆฌ ๊ธฐ๋ฅ(CRUD ์์ )
์ฌ์ฉ์: Auth0
์ ์ฒด ๊ฐ์ข์์ ์ฝ๊ฒ ์ดํดํ ์ ์๋๋ก ์์ ์ ๋ชจ๋ ๋ถ๋ถ์ ๋จ๋ ํ์ผ๋ก ๋๋ ๊ฒ์ ๋๋ค.
๋จผ์
core
๋๋ ํ ๋ฆฌ์ ๋ค์๊ณผ ๊ฐ์ ํด๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์์ต๋๋ค(๊ฐ ์น์
์ ๋ํด ๋
ผ์ํ ๋ ๊ฐ ํ์ผ์ ์
๋ฐ์ดํธํ ๊ฒ).|- src/app/core
|- state
|- menus
|- menus.actions.ts
|- menus.effects.ts
|- menus.reducer.ts
|- menus.selector.ts
|- menus.state.ts
|- index.ts
|- user
|- user.actions.ts
|- user.effects.ts
|- user.reducer.ts
|- user.selector.ts
|- user.state.ts
|- index.ts
|- core.state.ts
|- core.reducer.ts
|- index.ts
The starter app is using a
BehaviorSubject
inmenu-state.service.ts
to manage it's state. This tutorial will walk you through migrating that to NgRx.
๋ฉ๋ด ์ํ ๊ด๋ฆฌ
๋ฉ๋ด ์ํ ๋ง๋ค๊ธฐ
๋ฉ๋ด์ ์ํ ๋์์ ๋ง๋๋ ๊ฒ๋ถํฐ ์์ํฉ๋๋ค.
menus.state.ts
์ ์ด๊ณ ๋ค์ ์ฝ๋๋ฅผ ์ถ๊ฐํ์ญ์์ค๐Read more...
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ Angular์์ NgRx๋ฅผ ์ฌ์ฉํ ์ํ ๊ด๋ฆฌ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/robertinoc_dev/state-management-in-angular-using-ngrx-1hloํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค