SlideShare a Scribd company logo
1 of 117
Gerenciamento de estado
no Angular com NgRx
Loiane Groner
@loiane
github.com/loiane
loiane.com
loiane.training
Java, JavaScript/HTML5,
Sencha, Angular, Phonegap/
Ionic
Disponível (inglês) na amazon.com.br
https://novatec.com.br/livros/estruturas-de-dados-algoritmos-em-javascript/
Entender como
desenvolver projetos
reativos com Angular
Entender como
desenvolver projetos
reativos com Angular
#itsJustAngular
Programação
eativa
http://www.reactivemanifesto.org/pt-BR
Manifesto Reativo
Reagir a informações
Reagir a usuários
Reagir a erros
Reage a dados que são
transmitidos ao longo
do tempo
Extensões reativas (RxJS)
http://reactivex.io/
Objeto Promise
Iterable Observable
Síncrono Assíncrono
ValorúnicoMúltiplosvalores
Panorama da teoria da reatividade
Padrões
eativos
Gerenciar o estado e
controle de fluxo
COMPONENTE
{…}
TEMPLATE
<..>
COMPONENTE
{…}
TEMPLATE
<..>
Binding de
Propriedades
COMPONENTE
{…}
TEMPLATE
<..>
Binding de
Propriedades
Binding de
Eventos
COMPONENTE
{…}
TEMPLATE
<..>
DIRETIVAS
{..}
Binding de
Propriedades
Binding de
Eventos
COMPONENTE
{…}
TEMPLATE
<..>
DIRETIVAS
{..}
SERVIÇOS
SERVIÇO A
SERVIÇO B
Binding de
Propriedades
Binding de
Eventos
COMPONENTE
{…}
TEMPLATE
<..>
DIRETIVAS
{..}
SERVIÇOS
SERVIÇO A
SERVIÇO B MÓDULO X
MÓDULO A
MÓDULO B
Binding de
Propriedades
Binding de
Eventos
Yay! Projeto novo em Angular!
COMPONENTE
{…}
SERVIÇO
COMPONENTE
{…}
SERVIÇO
COMPONENTE
{…}
SERVIÇO
COMPONENTE
{…}
SERVIÇO
COMPONENTE
{…}
SERVIÇO
uma semana depois…
@Component({
selector: 'app-product-order',
templateUrl: './product-order.component.html',
styleUrls: ['./product-order.component.scss']
})
export class ProductOrderComponent implements OnInit {
constructor(
private router: Router,
private route: ActivatedRoute,
private location: Location,
private productService: ProductService,
private clientService: ClientService,
private addressService: AddressService,
private userRoleService: UserRoleService,
private comboboxService: ComboboxService,
private exportFileService: ExportPDFService
) {}
}
COMPONENTE
{…}
SERVIÇO
COMPONENTE
{…}
COMPONENTE
{…}
COMPONENTE
{…}
SERVIÇO
SERVIÇO SERVIÇO SERVIÇO
COMPONENTE
{…}
SERVIÇO
@Injectable()
export class AuthService {
private loggedIn = new BehaviorSubject<boolean>(false);
get isLoggedIn() {
return this.loggedIn.asObservable();
}
login(user: User){
if (valid.userName !== '' && user.password != ‘') {
this.loggedIn.next(true);
}
}
logout(){
this.loggedIn.next(false);
}
}
O maior problema no desenvolvimento e
manutenção de sistemas de software de
grande escala é a complexidade -
sistemas grandes são difíceis de
entender
Ben Moseley & Peter Marks
Out of the Tar Pit: Analysis of Software Complexity
Acreditamos que o principal contribuinte
para esta complexidade em muitos
sistemas é o gerenciamento do estado e
o fardo que isso acrescenta ao tentar
analisar e entender o sistema. Outros
contribuintes estreitamente relacionados
são o volume do código e a preocupação
com o controle de fluxo do sistema.
Ben Moseley & Peter Marks
Out of the Tar Pit: Analysis of Software Complexity
Redux é uma
biblioteca, e também é
um padrão
Redux é uma
biblioteca, e também é
um padrão reativo
sem Redux
Componente iniciando a mudança
Não reativo
Variável comum <number>
Não reativo
Estado
com Redux
Estado
Redux Store
Ação
dispatch
subscribe
Passo 1: Definir actions
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
export const RESET = 'RESET';
Passo 2: Definir estado inicial e reducer
export const counterReducer: ActionReducer<number> = (
state: number = 0,
action: Action
) => {
switch (action.type) {
case INCREMENT:
return state + 1;
case DECREMENT:
return state - 1;
case RESET:
return 0;
default:
return state;
}
};
Passo 2: Definir estado inicial e reducer
export const counterReducer: ActionReducer<number> = (
state: number = 0,
action: Action
) => {
switch (action.type) {
case INCREMENT:
return state + 1;
case DECREMENT:
return state - 1;
case RESET:
return 0;
default:
return state;
}
};
Recebe o estado inicial
Passo 2: Definir estado inicial e reducer
export const counterReducer: ActionReducer<number> = (
state: number = 0,
action: Action
) => {
switch (action.type) {
case INCREMENT:
return state + 1;
case DECREMENT:
return state - 1;
case RESET:
return 0;
default:
return state;
}
};
Recebe o estado inicial
Recebe a ação + payload
Passo 2: Definir estado inicial e reducer
export const counterReducer: ActionReducer<number> = (
state: number = 0,
action: Action
) => {
switch (action.type) {
case INCREMENT:
return state + 1;
case DECREMENT:
return state - 1;
case RESET:
return 0;
default:
return state;
}
};
Recebe o estado inicial
Recebe a ação + payload
Retorna novo estado
baseado na ação
reducer Novo Estado
Estado
Ação
dispatch
+
store
Flow de dados unidirecional com Redux
Reducer Store Component
Ações
subscribe
dispatch
https://github.com/ngrx
Flow de dados unidirecional com NgRx
Reducer Component
subscribe
dispatch
Store
Ações
import { StoreModule } from '@ngrx/store';
import { counterReducer } from './reducers/counter';
@NgModule({
imports: [
StoreModule.provideStore({ counter: counterReducer })
]
})
export class AppModule { } Reducers Globais
Store API
// seleciona todo o estado
this.store.select(state => state);
// seleciona parte do estado
this.store.select(state => state.tasks);
this.store.select('tasks');
// dispara ações
this.store.dispatch({
type: 'ACTION_TYPE',
payload: {...}
});
Store API
// seleciona todo o estado
this.store.select(state => state);
// seleciona parte do estado
this.store.select(state => state.tasks);
this.store.select('tasks');
// dispara ações
this.store.dispatch({
type: 'ACTION_TYPE',
payload: {...}
});
Store API
// seleciona todo o estado
this.store.select(state => state);
// seleciona parte do estado
this.store.select(state => state.tasks);
this.store.select('tasks');
// dispara ações
this.store.dispatch({
type: 'ACTION_TYPE',
payload: {...}
});
@Component({
template: `
<div>Counter: {{ counter }}</div>
`
})
export class CounterComponent {
counter: number;
counterSub: Subscription;
ngOnInit() {
this.counterSub = Observable.interval(1000)
.startWith(0)
.subscribe(counter => (this.counter = counter));
}
ngOnDestroy() {
this.counterSub.unsubscribe();
}
}
@Component({
template: `
<div>Counter: {{ counter }}</div>
`
})
export class CounterComponent {
counter: number;
counterSub: Subscription;
ngOnInit() {
this.counterSub = Observable.interval(1000)
.startWith(0)
.subscribe(counter => (this.counter = counter));
}
ngOnDestroy() {
this.counterSub.unsubscribe();
}
}
@Component({
template: `
<div>Counter: {{ counter }}</div>
`
})
export class CounterComponent {
counter: number;
counterSub: Subscription;
ngOnInit() {
this.counterSub = Observable.interval(1000)
.startWith(0)
.subscribe(counter => (this.counter = counter));
}
ngOnDestroy() {
this.counterSub.unsubscribe();
}
}
@Component({
template: `
<div>Counter: {{ counter }}</div>
`
})
export class CounterComponent {
counter: number;
counterSub: Subscription;
ngOnInit() {
this.counterSub = Observable.interval(1000)
.startWith(0)
.subscribe(counter => (this.counter = counter));
}
ngOnDestroy() {
this.counterSub.unsubscribe();
}
}
@Component({
template: `
<div>Counter: {{ counter }}</div>
`
})
export class CounterComponent {
counter: number;
counterSub: Subscription;
ngOnInit() {
this.counterSub = Observable.interval(1000)
.startWith(0)
.subscribe(counter => (this.counter = counter));
}
ngOnDestroy() {
this.counterSub.unsubscribe();
}
}
http://tradingadvantagedaily.com/wp-content/uploads/2017/07/1c00898.jpg
@Component({
template: `Counter: {{ counter$ | async }}`
})
export class CounterComponent {
counter$: Observable<number>;
ngOnInit() {
this.counter$ = Observable.interval(1000).startWith(0);
}
}
@Component({
template: `Counter: {{ counter$ | async }}`
})
export class CounterComponent {
counter$: Observable<number>;
ngOnInit() {
this.counter$ = Observable.interval(1000).startWith(0);
}
}
@Component({
template: `Counter: {{ counter$ | async }}`
})
export class CounterComponent {
counter$: Observable<number>;
ngOnInit() {
this.counter$ = Observable.interval(1000).startWith(0);
}
}
Integrando com a Store
@Component({…})
export class CounterComponent {
counter$: Observable<number>;
constructor(private store: Store<number>) {}
ngOnInit() {
this.counter$ = this.store.select<number>('counter');
}
}
Integrando com a Store
@Component({…})
export class CounterComponent {
counter$: Observable<number>;
constructor(private store: Store<number>) {}
ngOnInit() {
this.counter$ = this.store.select<number>('counter');
}
}
(1): Declarar Observable
Integrando com a Store
@Component({…})
export class CounterComponent {
counter$: Observable<number>;
constructor(private store: Store<number>) {}
ngOnInit() {
this.counter$ = this.store.select<number>('counter');
}
}
(1): Declarar Observable
(2): Injetar Store
Integrando com a Store
@Component({…})
export class CounterComponent {
counter$: Observable<number>;
constructor(private store: Store<number>) {}
ngOnInit() {
this.counter$ = this.store.select<number>('counter');
}
} (3): Obter estado relacionado ao Component
Template
<div class="content">
<button (click)="increment()">+</button>
<button (click)="decrement()">-</button>
<button (click)="reset()">Reset Counter</button>
<h3>{{counter$ | async}}</h3>
</div>
Template
<div class="content">
<button (click)="increment()">+</button>
<button (click)="decrement()">-</button>
<button (click)="reset()">Reset Counter</button>
<h3>{{counter$ | async}}</h3>
</div>
Observable<number>
Eventos === Actions
increment() {
this.store.dispatch({ type: INCREMENT });
}
decrement() {
this.store.dispatch({ type: DECREMENT });
}
reset() {
this.store.dispatch({ type: RESET });
}
CRUD com Ajax
Definir ações
export enum TaskActions {
LOAD = '[Task] LOAD Requested',
LOAD_SUCCESS = '[Task] LOAD Success',
CREATE = '[Task] CREATE Requested',
CREATE_SUCCESS = '[Task] CREATE Success',
UPDATE = '[Task] UPDATE Requested',
UPDATE_SUCCESS = '[Task] UPDATE Success',
REMOVE = '[Task] REMOVE Requested',
REMOVE_SUCCESS = '[Task] REMOVE Success',
ERROR = '[Task] Error'
}
Definir ações
Definir ações
export class LoadAction extends NgRxAction<any> {
type = TaskActions.LOAD;
}
export class LoadSuccessAction extends NgRxAction<Task[]> {
type = TaskActions.LOAD_SUCCESS;
}
No componente
No componente
Evento de pedido para carregar a informação do servidor
No componente
Evento de pedido para carregar a informação do servidor
Reducer
Reducer
NÃO mudar o estado diretamente
Estado deve ser imutável
Reducer
NÃO mudar o estado diretamente
Estado deve ser imutável
Reducer DEVE ser uma função PURA
Programação Funcional
Components: Dumb Components
<li class="collection-item">
<span [class.task-completed]="task.completed">{{ task.title }}</span>
<a class="secondary-content btn-floating"
(click)="onRemove()">
<i class="material-icons circle">delete</i>
</a>
<a class="secondary-content btn-floating"
(click)="onComplete()">
<i class="material-icons circle">done</i>
</a>
</li>
Components: Dumb Components
@Component({})
export class TaskItemComponent {
@Input() task: Task;
@Output() remove: EventEmitter<any> = new EventEmitter(false);
@Output() complete: EventEmitter<any> = new EventEmitter(false);
onRemove() {
this.remove.emit();
}
onComplete() {
this.complete.emit({
completed: !this.task.completed
});
}
}
Containers: Smart Components
<div class="row">
<div class="col s6 offset-s3 input-field">
<app-task-form (createTask)=“onCreateTask($event)">
</app-task-form>
<app-tasks-list
[tasks]="tasks$"
(remove)="onRemoveTask($event)"
(complete)="onUpdateTask($event)"
>
</app-tasks-list>
</div>
</div> Escutam os eventos dos
Componentes filhos e fazem o
dispatch
Containers: Smart Components
<div class="row">
<div class="col s6 offset-s3 input-field">
<app-task-form (createTask)=“onCreateTask($event)">
</app-task-form>
<app-tasks-list
[tasks]="tasks$"
(remove)="onRemoveTask($event)"
(complete)="onUpdateTask($event)"
>
</app-tasks-list>
</div>
</div> Escutam os eventos dos
Componentes filhos e fazem o
dispatch
Mas e a comunicação com servidor?
Redux apenas se interessa pela estado do
cliente (frontend)
Store side effects
Efeitos Colaterais
@ngrx/effects
Effects
Escuta a ação de Pedido e faz dispatch da ação de
“Completo" - que atualiza o estado
@Effect()
loadAction$ = this.actions$
.ofType<task.LoadAction>(task.TaskActions.LOAD)
.map(action => action.payload)
.switchMap(payload =>
this.api
.load()
.map(res => new task.LoadSuccessAction(res))
.catch(error => this.handleError(error))
);
😍
Service API
o Serviço da API não sabe do estado nem do redux
@Injectable()
export class TaskService {
private readonly API_TASKS_URL = `http://localhost:3001/tasks`;
constructor(private http: HttpClient) {}
load() {
return this.http.get<Task[]>(this.API_TASKS_URL);
}
create(record: Task) {
return this.http.post<Task>(this.API_TASKS_URL, record);
}
update(record: Task) {
return this.http.put<Task>(`${this.API_TASKS_URL}/${record.id}`, record);
}
remove(id: string) {
return this.http.delete<Task>(`${this.API_TASKS_URL}/${id}`);
}
}
Lazy Loading
@ngrx/platform (v4)
@NgModule({
imports: [
StoreModule.forFeature('task', taskReducer),
EffectsModule.forFeature([TaskEffects])
],
exports: [StoreModule, EffectsModule],
providers: [TaskStoreService]
})
export class TaskStoreModule {}
@NgModule({
imports: [
StoreModule.forRoot(reducers),
EffectsModule.forRoot([]),
StoreRouterConnectingModule,
!environment.production ? StoreDevtoolsModule.instrument({ maxAge: 50 }) : []
],
exports: [StoreModule]
})
export class AppStoreModule { }
@ngrx/platform (v4)
@NgModule({
imports: [
StoreModule.forFeature('task', taskReducer),
EffectsModule.forFeature([TaskEffects])
],
exports: [StoreModule, EffectsModule],
providers: [TaskStoreService]
})
export class TaskStoreModule {}
@NgModule({
imports: [
StoreModule.forRoot(reducers),
EffectsModule.forRoot([]),
StoreRouterConnectingModule,
!environment.production ? StoreDevtoolsModule.instrument({ maxAge: 50 }) : []
],
exports: [StoreModule]
})
export class AppStoreModule { }
Redux DevTools
Organização do Projeto
(opinião da Loiane)
Módulo Main:
App Store
Módulo Main:
App Store
Módulo Feature:
Feature Store
Boas Práticas
Estado
Evite Arrays!
Evite Arrays!
Prefira Dicionários (Object Literals)
RxJS CombineLatest
getCurrentTaskSelected() {
return Observable.combineLatest(
this.getTasks(),
this.store.select(this.selectCurrentTaskId),
(tasks, selectedId) => selectedId.map(id => tasks[id])
);
}
NgRx v5.x
@ngrx/entity
@ngrx/entity
import { createEntityAdapter, EntityAdapter, EntityState } from '@ngrx/entity';
import { Task } from './../model/task';
export interface TaskState extends EntityState<Task> {
isLoading: boolean;
selectedTaskId: any;
error: any;
}
export const taskAdapter: EntityAdapter<Task> = createEntityAdapter<Task>({
selectId: (task: Task) => task.id,
sortComparer: false,
});
export const taskInitialState: TaskState = taskAdapter.getInitialState({
isLoading: true,
selectedTaskId: null,
error: null
});
@ngrx/entity
import { createEntityAdapter, EntityAdapter, EntityState } from '@ngrx/entity';
import { Task } from './../model/task';
export interface TaskState extends EntityState<Task> {
isLoading: boolean;
selectedTaskId: any;
error: any;
}
export const taskAdapter: EntityAdapter<Task> = createEntityAdapter<Task>({
selectId: (task: Task) => task.id,
sortComparer: false,
});
export const taskInitialState: TaskState = taskAdapter.getInitialState({
isLoading: true,
selectedTaskId: null,
error: null
});
@ngrx/entity
import { createEntityAdapter, EntityAdapter, EntityState } from '@ngrx/entity';
import { Task } from './../model/task';
export interface TaskState extends EntityState<Task> {
isLoading: boolean;
selectedTaskId: any;
error: any;
}
export const taskAdapter: EntityAdapter<Task> = createEntityAdapter<Task>({
selectId: (task: Task) => task.id,
sortComparer: false,
});
export const taskInitialState: TaskState = taskAdapter.getInitialState({
isLoading: true,
selectedTaskId: null,
error: null
});
@ngrx/entity
export interface EntityState<T> {
ids: string[];
entities: Dictionary<T>;
}
export interface EntityStateAdapter<T> {
addOne<S extends EntityState<T>>(entity: T, state: S): S;
addMany<S extends EntityState<T>>(entities: T[], state: S): S;
addAll<S extends EntityState<T>>(entities: T[], state: S): S;
removeOne<S extends EntityState<T>>(key: string, state: S): S;
removeMany<S extends EntityState<T>>(keys: string[], state: S): S;
removeAll<S extends EntityState<T>>(state: S): S;
updateOne<S extends EntityState<T>>(update: Update<T>, state: S): S;
updateMany<S extends EntityState<T>>(updates: Update<T>[], state: S): S;
}
export declare type EntitySelectors<T, V> = {
selectIds: (state: V) => string[];
selectEntities: (state: V) => Dictionary<T>;
selectAll: (state: V) => T[];
selectTotal: (state: V) => number;
};
Reducer
case TaskActions.LOAD_SUCCESS: {
return ...taskAdapter.addMany(action.payload, state);
}
case TaskActions.CREATE_SUCCESS: {
return …taskAdapter.addOne(action.payload, state);
}
case TaskActions.UPDATE_SUCCESS: {
return
...taskAdapter.updateOne(
{ id: action.payload.id, changes: action.payload },
state
);
}
case TaskActions.REMOVE_SUCCESS: {
return {
...taskAdapter.removeOne(action.payload.id, state),
error: null
};
}
👏 👏 👏
VSCode
Em breve!
Prós e Contras:
1.Fluxo unidirecional ✅
2.Debug volta ao tempo (DevTools) ✅
3.Separação do código ✅
4.Fácil debug e bug fix (1, 2, e 3) ✅
5.Mais fácil pra testar devido à funções puras ✅
6.Melhor performance (onPush) ✅
7.Serialização do estado ✅
8.Mais uma camada == mais código ⛔
https://github.com/loiane/angular-ngrx4-example
Pra estudar mais…
• https://angular.io/docs/ts/latest/guide/reactive-forms.html
• https://angular.io/docs/ts/latest/guide/server-communication.html
• https://angular.io/docs/ts/latest/guide/router.html
• https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/categories.md
• https://gist.github.com/btroncone/d6cf141d6f2c00dc6b35
• http://rxmarbles.com/
• http://reactivex.io/documentation/operators
• https://github.com/ngrx
• https://github.com/ngrx/example-app
• https://auth0.com/blog/understanding-angular-2-change-detection/
• http://blog.brecht.io/A-scalable-angular2-architecture/
• http://blog.mgechev.com/2016/04/10/scalable-javascript-single-page-app-angular2-
application-architecture/
Obrigada!
@loiane
github.com/loiane
loiane.com
loiane.training
youtube.com/loianegroner

More Related Content

What's hot

Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideVictor Rentea
 
Les Streams de Java 8
Les Streams de Java 8Les Streams de Java 8
Les Streams de Java 8Antoine Rey
 
[Final] ReactJS presentation
[Final] ReactJS presentation[Final] ReactJS presentation
[Final] ReactJS presentation洪 鹏发
 
Genius Group Investor Presentation (May 2022).pptx
Genius Group Investor Presentation (May 2022).pptxGenius Group Investor Presentation (May 2022).pptx
Genius Group Investor Presentation (May 2022).pptxRoger Hamilton
 
Sql Basics | Edureka
Sql Basics | EdurekaSql Basics | Edureka
Sql Basics | EdurekaEdureka!
 
Database decommission process
Database decommission processDatabase decommission process
Database decommission processK Kumar Guduru
 
Introduction to React JS for beginners
Introduction to React JS for beginners Introduction to React JS for beginners
Introduction to React JS for beginners Varun Raj
 

What's hot (20)

Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
 
React with Redux
React with ReduxReact with Redux
React with Redux
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 
Ngrx: Redux in angular
Ngrx: Redux in angularNgrx: Redux in angular
Ngrx: Redux in angular
 
Les Streams de Java 8
Les Streams de Java 8Les Streams de Java 8
Les Streams de Java 8
 
[Final] ReactJS presentation
[Final] ReactJS presentation[Final] ReactJS presentation
[Final] ReactJS presentation
 
Tech Talk on ReactJS
Tech Talk on ReactJSTech Talk on ReactJS
Tech Talk on ReactJS
 
React hooks
React hooksReact hooks
React hooks
 
Genius Group Investor Presentation (May 2022).pptx
Genius Group Investor Presentation (May 2022).pptxGenius Group Investor Presentation (May 2022).pptx
Genius Group Investor Presentation (May 2022).pptx
 
Intro to Three.js
Intro to Three.jsIntro to Three.js
Intro to Three.js
 
Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
React js
React jsReact js
React js
 
Sql Basics | Edureka
Sql Basics | EdurekaSql Basics | Edureka
Sql Basics | Edureka
 
Le Wagon - React 101
Le Wagon - React 101Le Wagon - React 101
Le Wagon - React 101
 
Database decommission process
Database decommission processDatabase decommission process
Database decommission process
 
Introduction to React JS for beginners
Introduction to React JS for beginners Introduction to React JS for beginners
Introduction to React JS for beginners
 
React render props
React render propsReact render props
React render props
 
WebGL and three.js
WebGL and three.jsWebGL and three.js
WebGL and three.js
 

Similar to Gerenciamento de estado no Angular com NgRx

Battle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsBattle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsEvangelia Mitsopoulou
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeN Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeAnton Kulyk
 
Recompacting your react application
Recompacting your react applicationRecompacting your react application
Recompacting your react applicationGreg Bergé
 
React + Redux. Best practices
React + Redux.  Best practicesReact + Redux.  Best practices
React + Redux. Best practicesClickky
 
Evan Schultz - Angular Camp - ng2-redux
Evan Schultz - Angular Camp - ng2-reduxEvan Schultz - Angular Camp - ng2-redux
Evan Schultz - Angular Camp - ng2-reduxEvan Schultz
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Nir Kaufman
 
React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to HooksSoluto
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
What is new in sulu 2.0
What is new in sulu 2.0What is new in sulu 2.0
What is new in sulu 2.0danrot
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonfNataliya Patsovska
 
From zero to hero with the reactive extensions for java script
From zero to hero with the reactive extensions for java scriptFrom zero to hero with the reactive extensions for java script
From zero to hero with the reactive extensions for java scriptMaurice De Beijer [MVP]
 
Visualforce: Using JavaScript Remoting for Apex Controllers
Visualforce: Using JavaScript Remoting for Apex ControllersVisualforce: Using JavaScript Remoting for Apex Controllers
Visualforce: Using JavaScript Remoting for Apex Controllersprabhat gangwar
 
A Journey with React
A Journey with ReactA Journey with React
A Journey with ReactFITC
 

Similar to Gerenciamento de estado no Angular com NgRx (20)

Battle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsBattle of React State Managers in frontend applications
Battle of React State Managers in frontend applications
 
N Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React NativeN Things You Don't Want to Repeat in React Native
N Things You Don't Want to Repeat in React Native
 
Recompacting your react application
Recompacting your react applicationRecompacting your react application
Recompacting your react application
 
React + Redux. Best practices
React + Redux.  Best practicesReact + Redux.  Best practices
React + Redux. Best practices
 
Evan Schultz - Angular Camp - ng2-redux
Evan Schultz - Angular Camp - ng2-reduxEvan Schultz - Angular Camp - ng2-redux
Evan Schultz - Angular Camp - ng2-redux
 
Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016Redux with angular 2 - workshop 2016
Redux with angular 2 - workshop 2016
 
React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to Hooks
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
React hooks
React hooksReact hooks
React hooks
 
What is new in sulu 2.0
What is new in sulu 2.0What is new in sulu 2.0
What is new in sulu 2.0
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
 
Ngrx
NgrxNgrx
Ngrx
 
Side effects-con-redux
Side effects-con-reduxSide effects-con-redux
Side effects-con-redux
 
Understanding redux
Understanding reduxUnderstanding redux
Understanding redux
 
From zero to hero with the reactive extensions for java script
From zero to hero with the reactive extensions for java scriptFrom zero to hero with the reactive extensions for java script
From zero to hero with the reactive extensions for java script
 
Road to react hooks
Road to react hooksRoad to react hooks
Road to react hooks
 
Visualforce: Using JavaScript Remoting for Apex Controllers
Visualforce: Using JavaScript Remoting for Apex ControllersVisualforce: Using JavaScript Remoting for Apex Controllers
Visualforce: Using JavaScript Remoting for Apex Controllers
 
A Journey with React
A Journey with ReactA Journey with React
A Journey with React
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Ngrx meta reducers
Ngrx meta reducersNgrx meta reducers
Ngrx meta reducers
 

Recently uploaded

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024The Digital Insurer
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Angeliki Cooney
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfOverkill Security
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 

Recently uploaded (20)

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 

Gerenciamento de estado no Angular com NgRx