Create non-memoized selector on ngrx

半城伤御伤魂 提交于 2019-12-23 14:20:10

问题


Is it possible to create a non-memoized selector on ngrx?

I have a very small selector to check whether a value in the store is greater than Date.now().

export const selectAuthState = createFeatureSelector<AuthState>('auth');
export const hasTimeout = createSelector(
  selectAuthState,
  state => state.timeout < Date.now()
);

As expected, this selector is not useful since it won't be recalculated unless I change the value of timeout. Is there any way to make the selector non-memoized, so that it is recalculated every single time its value is accessed?

My current solution is creating a selector factory and using it every time, but I don't think it is the best solution:

export const hasTimeoutFactory = () => createSelector(
  selectAuthStatusState,
  state => state.timeout < Date.now()
);

Another solution would be doing something like

export const didTimeout = pipe(
  select(getTimeout), // using memoized value
  map(val => val < Date.now())
);

And then importing this pipe.


回答1:


A selector has a release method to reset the memoization, I think this is what you'd want to use.

This translates in the following code:

this.timeout = this.store.pipe(select(hasTimeout));
hasTimeout.release();

Docs




回答2:


I had a similar issue and did the following - I'm fairly sure it is wrong in terms of NgRx architecture but it does what I want it to do.

export const selectAuthorizationDetails = createSelector(selectAuthorizationState, 
    (state: AuthorizationState, store: Store<AuthorizationState>) => store,
    (state: AuthorizationState) => new Date(),     // Force the selector memoization to fail which is probably the wrong thing to do
      (state, store, timeNow) => {
        if (state.lastUpdated != null) {
            let diffMs = timeNow.getTime() - state.lastUpdated.getTime()
            if (diffMs > 300000) {
                store.dispatch(refreshAuthorization());
                return null;
            }
            return state.authorizationDetails;
        }
        return null;
      }
  );

In the store my authorization details store the last updated time and so on each invocation, it tests whether they've expired or not. If I use memoization then it won't work and releasing the selector then has to be done on each call meaning I'd probably need to hide the selector behind a facade.

When using the selector in an AuthGuard, I simply filter on null so that I can always get the most up to date version but can cache the results for a pre-determined time (5 mins in this example)



来源:https://stackoverflow.com/questions/50920308/create-non-memoized-selector-on-ngrx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!