Issue
I'm trying to convert my Ionic app to NgRx.
In one of my components I have a model variable that connects to a textarea like this:
component:
myTextVar: string = '';
template:
<ion-textarea ... [(ngModel)]="myTextVar" ...></ion-textarea>
So, trying to convert this to NgRx I created a field in the module reducer:
const textsFeatureKey = 'texts';
export interface TextsState {
...
myTextVar: string;
}
export const initialState: TextsState = {
...
myTextVar: '',
};
export const textsReducer = createReducer(
initialState,
...
on(TextsActions.setMyTextVar, (state, { myTextVar }) => ({ ...state, myTextVar })),
);
an action:
export const setMyTextVar = createAction('[Texts Page] Set myTextVar', props<{ myTextVar: string }>());
and a selector:
export const selectMyTextVar = (state: AppState) => state.texts.myTextVar;
Then in the component I changed this:
myTextVar$: Observable<string>;
constructor(
private store: Store<{ texts: any; }>
) {
...
this.myTextVar$ = this.store.select(selectMyTextVar)
}
ngOnInit() {
this.myTextVar$.subscribe(text => {
console.log('mtv debug', text);
})
this.store.dispatch(setMyTextVar({ myTextVar: 'some initial text'}));
...
}
So far so good... it loaded myTextVar in the textarea when I do it like this:
<ion-textarea [ngModel]="myTextVar$ | async" ></ion-textarea>
but now... How do I update the state ? I have done it like this:
<ion-textarea (ionInput)="onIonInputMyTextVar($event)" [ngModel]="myTextVar$ | async" ></ion-textarea>
and then in the component:
onIonInputMyTextVar(event: any) {
this.store.dispatch(setMyTextVar({ myTextVar: event.detail.value }));
}
This works. But isn't this too far fetched to just update a model var ? I have substituted 2 lines of code by a much larger and harder to maintain code having to handle ionInput event, reducer, selector, initialization, several selects along the code...
Makes me think I'm doing something wrong. Maybe there is a simpler way to convert ngModel vars or simply I shouldn't be using NgRx to handle simple variables cases in the component.
So my questions are:
- Am I doing this right ? Is there a simpler way to convert ngModel vars ?
- Should I really be doing this ? Isn't traditional
[(ngModel)]='myTextVar'
much cleaner for simple cases like this ? - This is a simple single component var. Where should NgRx really be used ? Should I use it only for multi-component data ?
Solution
You are confused because you missed one very important thing about NGRX store: it is used for global state management. "global" means at least on the module level.
But isn't this too far fetched to just update a model var ? I have substituted 2 lines of code by a much larger and harder to maintain code having to handle ionInput event, reducer, selector, initialization, several selects along the code
It looks like it is in your case. First of all, your component looks like a "dumb component", which means it shouldn't access external services at all. Secondly, the value produced by the component is not used anywhere, this means it shouldn't be in the global state. Thirdly, NGRX was created for large apps, not for any kind of tiny two-components-large side projects.
Before you decide to use any kind of state management library in future think about the data flow:
- If you collect some information in the component, immediately push it to the server and don't use this information or its derivatives elsewhere in the app, you don't need any kind of state
- If you collect some information in the component, immediately push it to the server and use this information or its derivatives in the [smart] component directly, you need a component store
- If you collect some information in the component, immediately push it to the server and use this information or its derivatives in other not related components or modules, you need an application-wide store
Of course, there are certain exceptions but this is a different topic.
BTW, it is also okay if in the project where NGRX is used some of the components don't use NGRX. You don't have to always push every bit of information in the global state.
Answered By - Volodymyr Usarskyy
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.