My app already has a large collection of selectors used by the various container objects. These are great for accessing different parts of the state and make refactoring the state much easier.
Now I want to use my selectors inside some of my reducer functions. The problem is that inside the reducer, the state
parameter refers to a specific slice of the state, whereas the selector functions expect to be called with the state root object.
Contrived Example:
/* Selectors */
const getTodos = state => state.todos;
const getUncompletedTodos = createSelector(
[ getTodos ],
todos => todos.filter(t => !t.completed)
);
/* Reducer */
const todosReducer = (state, action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
];
case 'REMOVE_COMPLETED_TODOS':
return getUncompletedTodos(state); // <-- this won't work
}
}
You selector works from root state object.
To fake this you could do
return getUncompletedTodos({todos: state});
But IMHO a better idea would be to reuse filtering function
/* Selectors */
const getTodos = state => state.todos;
const filterCompleted = todos => todos.filter(t => !t.completed)
const getUncompletedTodos = createSelector(
[ getTodos ],
filterCompleted
);
// inside reducer
case 'REMOVE_COMPLETED_TODOS':
return filterCompleted(state);