如何让NGRX/Redux在存储中的数据未更改时停止向订阅者传输数据?

huus2vyu  于 2023-03-02  发布在  其他
关注(0)|答案(2)|浏览(110)

当用户在MatchingPairsComponent中完成一个测试时,调用以下函数将用户的结果传输到后端。

private updateUserTestRecord = (testType) => {
const newTestRecord = {
    topicName: this.topicName,
    subtopicName:this.subtopicName,
    rightAnswers: 'n/a',
    wrongAnswers: this.wrongMatches + ' of ' + this.matchingPairsLength,
    testType,
    date: new Date(),            
}

  this.userService.updateUserTestRecord(newTestRecord)
 }

上面调用的UserService函数将用户数据传输到后端,如下所示:

public updateUserTestRecord = (newTestRecord) => {
this.httpClient
  .put<{ testRecords }>(`${this.url}/update/user/record`, newTestRecord).pipe(
    tap(testRecords => {
      console.log('testRecords',  testRecords)
      this.store.dispatch(userActions.SaveTestRecords({ testRecords }));
    }),
    catchError((errorObj) => {
      this.store.dispatch(
        messageActions.SetError({ error: errorObj.error })
      );
      throw errorObj;
    })
  ).subscribe();
 }

上述函数接收后台更新的测试记录,并更新UserReducer,UserReducer函数如下图所示:

on(userActions.SaveTestRecords, (state, action) => {
console.log('SaveTestRecords.testRecords', action.testRecords)
const currentState =  {
    ...state,
    testRecords: action.testRecords     
}

saveStateToLocalStorage(currentState);

return currentState;
 }),

问题是当UserService更新UserReducer时,数据也从TopicsReducer传输到订阅TopicsReducer的MatchingPairsComponent,即使TopicsReducer中的数据没有改变。
重复一遍,UserReducer被更新,但是数据从TopicReducer传输到MatchingPairsComponent,即使TopicReducer从未被更新。下面是MatchingPairsComponent订阅的TopicReducer函数:

export const TopicsReducers = createReducer(initialState,
on(topicsActions.StoreSubtopicData, (state, action) => { 
  console.log('Storetopics.topics', action.subtopicData)   
  return {
    ...state,
    subtopicData: action.subtopicData,
  };
}),)

下面是MatchingPairsComponent对TopicsReducer的订阅:

ngOnInit() {
   this.subscribeToReduxStores();     
 }

 private subscribeToReduxStores = () => {
window.speechSynthesis.cancel();

const topicQuestions$ = this.store.select((state) => {      
  console.log('state.topicsState', state.topicsState)

  return {
    matchingPairs: state.topicsState.matchingPairs, 
    subtopicName: state.topicsState.subtopicData.subtopicName,
    topicName: state.topicsState.subtopicData.topicName,        
  }
})

topicQuestions$.subscribe(data => {    
  console.log('topicQuestions.subscribe', data); 
  this.matchingPairs = JSON.parse(JSON.stringify(data.matchingPairs));   
  this.matchingPairsLength = this.matchingPairs.length;   
  this.topicName = data.topicName; 
  this.subtopicName = data.subtopicName;       
  this.numberOfSegments = Math.ceil(this.matchingPairs.length/this.MAXPAIRS);
  this.wrongMatches = 0;
  console.log('matchingPairs', this.matchingPairs)
  this.setupPairs(); 
})

}
TopicsReducer中的数据没有更改时,为什么TopicsReducer要将数据传输到MatchingPairsComponent,覆盖MatchingPairsComponent中当前正在处理的数据?

6l7fqoea

6l7fqoea1#

已将MatchingPairsComponent订阅的选择语句更改为redux,以仅返回“state. topicsState”。

const topicQuestions$ = this.store.select((state) => {      
  console.log('state.topicsState', state.topicsState)

  // return {
  //   // matchingPairs: state.topicsState.matchingPairs, 
  //   // subtopicName: state.topicsState.subtopicData.subtopicName,
  //   // topicName: state.topicsState.subtopicData.topicName,        
  // }

  return state.topicsState
})

相应地更改了订阅语句以使用topicsState:

topicQuestions$.subscribe(topicsState => {    
  console.log('topicQuestions.subscribe', topicsState); 
  this.matchingPairs = JSON.parse(JSON.stringify(topicsState.matchingPairs));   
  this.matchingPairsLength = this.matchingPairs.length;   
  this.topicName = topicsState.subtopicData.topicName; 
  this.subtopicName = topicsState.subtopicData.subtopicName;       
  this.numberOfSegments = Math.ceil(this.matchingPairs.length/this.MAXPAIRS);
  this.wrongMatches = 0;
  console.log('matchingPairs', this.matchingPairs)
  this.setupPairs(); 
})
unftdfkk

unftdfkk2#

@koque在这里是正确的,我相信由于你的代码当前返回的是一个具有多个状态切片的对象,所以对其中任何一个状态的任何更改都将更新整个topicQuestions$可观察对象。
既然您使用的是NgRx,那么您能够合并Selectors吗?它添加了一些代码,但是它使得选择状态切片更容易处理和读取。

相关问题