NGRX / RXJS动作道具变得不可变

发布于 2025-02-14 02:13:08 字数 1732 浏览 1 评论 0原文

我发现我发送到动作的道具(EX:具有搜索标准发送到API的类模型)正在变得不可变,我无法修改该类的属性。

现在,我知道还原器 /商店对象是不可变的,但是该类在任何时候都不会触摸还原器或进入商店。

我已经与NGRX合作了几年,我遇到了一些我没有意识到的行为,或者是新的。也许我完全缺少其他地方的东西,但是任何见解都会受到赞赏...

采取这种简单的行动,该操作会采取班级道具来代表请求:

export const loadNotes= createAction('[Notes] Load Notes',
  props<{ getNotesRequestModel: GetNotesRequestModel }>()
);

然后为此动作发动效果,以调用加载注释的服务:

loadNote$ = createEffect(() =>
this.actions$.pipe(
  ofType(NoteActions.loadNotes),
  switchMap((action) =>
    from(
      this.noteService.getNotesList(action.getNotesRequestModel)
    ).pipe(
      map((response) => {
        return NoteActions.loadNotesSuccess({ response });
      }),
      catchError((error) => {
        return of(NoteActions.loadNoteFail());
      })
    )
  )
)
);

最后,最后还原器处理存储在状态下的响应:

  on(NoteActions.loadNotesSuccess,(state: INoteState, { response }) => ({
    ...state,
    noteResponse: response,
  })),

这一切都很好,除了首次调用操作之后,local getNotesRequestModel变量现在不变了,这使我无法更改页面等属性等。对API的后续电话。

但是,如果我修改调度以克隆请求对象,则可以正常工作。

public getNotes(){    
  this.noteStore.dispatch(
    NotesActions.loadNotes({getNotesRequestModel: _.cloneDeep(this.noteRequest)})
  );
}

更新:

NGRX版本历史记录的研究表明,从8.6版到9版,默认情况下,严格的动作不变性设置为True。我忘记了这一点,以及为什么我以前没有经历过这种行为。

如果需要,可以通过储藏装置来控制严格的不变性,如下所示:

@NgModule({
declarations: [
  AppComponent,
],
imports: [
  BrowserModule,
  StoreModule.forRoot(reducers, {
    metaReducers,
    runtimeChecks: {
      strictStateImmutability: true,
      strictActionImmutability: true
    }
  }),
  .....
],
providers: [],
bootstrap: [AppComponent]
})

I am finding that props that I send into actions (ex: a class model with search criteria to send to the API) are becoming immutable and I can not modify the properties of that class.

Now, I understand that reducer / store objects are immutable, but this class is never touching a reducer or getting into the store at any point.

I have been working with Ngrx for a couple of years now and I just came across some behavior that I either didn't realize was there or is new. Perhaps I am missing something entirely somewhere else, but any insight is appreciated...

Take this simple action that takes in a class prop to represent a request:

export const loadNotes= createAction('[Notes] Load Notes',
  props<{ getNotesRequestModel: GetNotesRequestModel }>()
);

An effect then fires for this action to call a service that loads the notes:

loadNote$ = createEffect(() =>
this.actions$.pipe(
  ofType(NoteActions.loadNotes),
  switchMap((action) =>
    from(
      this.noteService.getNotesList(action.getNotesRequestModel)
    ).pipe(
      map((response) => {
        return NoteActions.loadNotesSuccess({ response });
      }),
      catchError((error) => {
        return of(NoteActions.loadNoteFail());
      })
    )
  )
)
);

Finally, a reducer handles storing the response in state:

  on(NoteActions.loadNotesSuccess,(state: INoteState, { response }) => ({
    ...state,
    noteResponse: response,
  })),

This all works fine, except that the after the action is first called, the local getNotesRequestModel variable is now immutable, which prevents me from changes to the properties like pageing, etc. to make followup calls to the API.

However, if I modify the dispatch to clone the request object, it works fine.

public getNotes(){    
  this.noteStore.dispatch(
    NotesActions.loadNotes({getNotesRequestModel: _.cloneDeep(this.noteRequest)})
  );
}

Update:

Research of the Ngrx version history shows that from version 8.6 to 9, strict action immutability was set to true by default. I had forgotten this and why I had not experienced the behavior before.

If desired, strict immutability can be controlled through the StoreModule setup as follows:

@NgModule({
declarations: [
  AppComponent,
],
imports: [
  BrowserModule,
  StoreModule.forRoot(reducers, {
    metaReducers,
    runtimeChecks: {
      strictStateImmutability: true,
      strictActionImmutability: true
    }
  }),
  .....
],
providers: [],
bootstrap: [AppComponent]
})

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

太阳公公是暖光 2025-02-21 02:13:08

道具将被发送到操作,因此对象被NGRX标记为ReadOnly,因此在您发送事件的时间并进行处理之间,操作的值不会更改。

当您传递对对象的引用时,整个对象都可以像样。

The props will be sent to the action, so the object is marked as readonly by ngrx so that between the time you sent the event and it is processed, the value of the action doesn't change.

As you are passing a reference to an object, this entire object is made imutable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文