0

According to the NgRx documentation Reducers and Selectors are pure functions.

"Reducers are pure functions in that they produce the same output for a given input."

"Because selectors are pure functions, the last result can be returned when the arguments match without reinvoking your selector function."

Consider the following simple example

 export const AppState = {
  dataArray: []
}

// A Simple action that adds to the dataArray (created by Action creator)
export const addAction = createAction('Add to dataArray', props<{ data:number }>())

// Initial state of dataArray is an empty array
const initialDataArray = [];

// A simple reducer to get new state (created by Reducer creator)
// The new data element is simply added to the previous dataArray and a new Array is returned
export const dataArrayReducer = createReducer(initialDataArray,
                                              on(addAction, (state, newData) => ([...state.dataArray, newData])))


// A selector to get the dataArray
export const selectDataArray = (state: AppState) => state.dataArray;
 
// Suppose we dispatch actions to the store
store.dispatch(addAction(1)); // Reducer will return state : { dataArray : [1] }
store.dispatch(addAction(1)); // Reducer will return state : { dataArray [1, 1] }
// Different states returned even though the input was the same Action with same props

const dataArray$ = store.pipe(select(selectDataArray)); // [1, 1]

store.dispatch(addAction(1));

const dataArray2$ = store.pipe(select(selectDataArray)); // [1, 1, 1]
// We get different values from the same selector.

So as we can see we get different values from the Reducer and Selector even when we provide the exact same arguments. So how can they be considered Pure functions?

Am I missing something? Did I get the definitions of Pure functions wrong?

Devesh Pradhan
  • 149
  • 1
  • 6

1 Answers1

0

After a little pondering, I found the answer to my question.

The key to remember is that both the Reducers and Selectors take the State as an argument in addition to other arguments. The createReducer and createSelector functions return a Reducer and Selector function to which the state must be passed.

So for a given state the same arguments would return the same values always and that is why they are pure functions.

The first time addAction is dispatched the state is { dataArray = [] } The second time addAction is dispatched the state is { dataArray = [1] }

Hence we get different values from the Reducer.

Similarly for the selector the first time the selector is called the state is { dataArray = [1, 1] } and the second time it is called the state is { dataArray = [1, 1, 1] }.

And hence the selector too returned different values each time.

Devesh Pradhan
  • 149
  • 1
  • 6