在商店

时间:2018-06-06 19:59:48

标签: angular ngrx reselect

我和nularx的Angular 5应用程序。我在商店里有一个对象数组。当我订阅获取此数组时,即使我没有更改 state.details.selectedOptions,也会触发更改事件。我只更改了 state.details.page 并调用了订阅者

当我将 state.details.selectedOptions 更改为普通值(字符串)时,一切都按预期工作。我看到问题出在数组/嵌套元素中?

//store
const initialState = {
  page: null,
  selectedOptions: []
}
// selector
export const selectedOptionsSelector =  createSelector(
  (state: any) => state.details.selectedOptions
)
// also tried such variant
export const selectedOptionsSelector = (state: any) => state.details.selectedOptions
// Component
ngOnInit() {
  this.store.select(selectedOptionsSelector).subscribe((res: any) => {
    console.log('selectedOptions', res)
  })
}

更新

基本上在我的情况下,我在selectedOptions中总是有空数组,因为初始状态没有改变。我尝试在select中使用distinctUntilChanged,但它没有帮助

1 个答案:

答案 0 :(得分:1)

很难确定,因为您还没有添加reducer定义,但是正如您所说的,您始终将selectedOptions设置为一个空数组,我认为您的意思是在您的reducer中您有一个操作来更新页面,以及何时分派动作后,您将其状态修改为:

case Actions.Type.UPDATE_PAGE: {
    return {
        ...state,
        page: 'newValue',
        selectedOptions: []
    }
}

Redux使用浅层相等性检查来确定状态是否已更改。正如@Roomy所说,[“ a”] === [“ a”]返回false,因此Redux将在分配新引用时将以上内容视为对state.selectedOptions的更改。 使用distinctUntilChanged()并没有什么区别,因为它使用浅层相等性检查,因此,如果您传递两个具有不同引用的数组,它将认为这是一个更改。

如果您只需要更新页面,则仅更新页面属性,并保留selectedOptions不变:

case Actions.Type.UPDATE_PAGE: {
    return {
        ...state,
        page: 'newValue'
    }
}

这样,您的组件中的观察者将不会收到selectedOptions更改的通知。

您也可以使用

case Actions.Type.UPDATE_PAGE: {
            return {
                ...state,
                page: 'newValue',
                selectedOptions: state.selectedOptions
            }
}

因为在这种情况下selectedOptions仍将指向相同的引用。虽然这没有意义,但可以帮助解释这一点。