Boky Boky - 2 months ago 5
React JSX Question

Adding function to reducer

My reducer is as follows :

const removeFilter = (state, name) => {
return state.filter(f => f.name !== name);
};

export default function addRemoveFilterReducer(state = [], action) {
switch (action.type) {

case ADD_FILTER:
if(!state.some(i => i.name === action.searchFilter.name))
return [...state, {name: action.searchFilter.name, values: [action.searchFilter.values]}];
else
return [...state.filter(f => f.name !== action.searchFilter.name), {name: action.searchFilter.name, values: [action.searchFilter.values]}];

case REMOVE_FILTER:
return [...state.filter(f => f.name !== action.searchFilter.name)];
break;

default:
return state;
}
}


In else state of ADD_FILTER case and in REMOVE_FILTER case I have the same code :
...state.filter(f => f.name !== action.searchFilter.name)
.

I created a function remove filter with that code. How can I now use this function in my cases?

I tried with
return [removeFilter(state, action.searchFilter.name, {name: action.searchFilter.name, values: [action.searchFilter.values]}];
in else state of ADD_FILTER case, but it doesn't work.

Any advice?

UPDATE

The function call :

return [removeFilter(state, action.searchFilter.name, ......];

Answer

I suggest to change your code in this way:

export default function addRemoveFilterReducer(state = [], action) {
    switch (action.type) {

        case ADD_FILTER:
            let nState = state;
            if(state.some(i => i.name === action.searchFilter.name)) {
               nState = state.filter(f => f.name !== action.searchFilter.name);
            }

            return [...nState, {name: action.searchFilter.name, values: [action.searchFilter.values]}];

        case REMOVE_FILTER:
            return state.filter(f => f.name !== action.searchFilter.name);

        default:
            return state;
    }
}

Now you have splitted up the remove from the add and the code is much clear than was before.

So on your function now:

const removeFilter = (state, name) => {
    return state.filter(f => f.name !== name);
};


export default function addRemoveFilterReducer(state = [], action) {
    switch (action.type) {

        case ADD_FILTER:
            let nState = state
            if(state.some(i => i.name === action.searchFilter.name)) {
               nState = removeFilter(state, action.searchFilter.name);
            }

            return [...nState, {name: action.searchFilter.name, values: [action.searchFilter.values]}];

        case REMOVE_FILTER:
            return removeFilter(state, action.searchFilter.name);

        default:
            return state;
    }
}

You already have an array from the function, so you don't need the put it into another array and use the spread operation.

If you need to clone the state object, than do it inside the function, as it is the right place.

Hope this helps.

Comments