Redux reducer with a filter I'm wondering if my approach to creating a filtered array (filteredLaunches) from an array of data (launches) is an anti-pattern, or not? Is there a better way to go about it?

Here is the code:



const initialState = {
  launches: [],
  filteredLaunches: []
};

export default function(state = initialState, action) {

  switch (action.type) {

    case 'getLaunches':
      return Object.assign({}, state, {
        launches: action.launches
      });

    case 'filterLaunches':

      let filteredLaunches = [];

      for (let i = 0; i &lt; state.launches.length; i++) {
        if (action.location === state.launches[i].location.countryCode)
          filteredLaunches.push(state.launches[i]);
      }

      return Object.assign({}, state, {
        filteredLaunches: filteredLaunches
      });

    default:
      return state;
  }
};
Well, you could use Array.filter to filter the launches.

...
case 'filterLaunches':
  return Object.assign({}, state, {
    filteredLaunches: state.launches.filter(function(launch) {
      return action.location === launch.location.countryCode
    })
  }
default:
 return state;


The other question is, why not filtering inside the Component directly?

Because your next problem will be, that each time you add launches, you will have to filter them and copy again, and again.

So to not create duplicates, it's better to set the filter in the reducer and perform the filtering inside the render 

So: 

export default function(state = initialState, action) {
  case 'SET_LAUNCHES':
    return {...state, launches: action.launches };
  case 'SET_FILTER':
    return {...state, filter: action.filter };
  default:
    return state;
}

export function filterLaunches(launches, filter = {location: 'ES'} ) {
  const filterKeys = Object.keys(filter);
  return launches.filter((launch) =&gt; {
    return filterKeys.reduce((acc, key) =&gt; acc &amp;&amp; launch[key] === filter[key], true)
  });
}

// Then in the component
import { filterLaunches } from '../launchesStore';

const LaunchesList = ({launches, filter}) =&gt; (
  &lt;ul&gt;
    {filterLaunches(launches, filter).map((launch) =&gt; (
      &lt;li&gt;Launch: {launch.name}&lt;/li&gt;
    ))}
  &lt;/ul&gt;
);

export default connect(LaunchesList);


It's good to keep the filterLaunches function next to the reducer, because this function is very related to this part of the state and if you change the format like from an array to a map-by-id you would have to change that function only in one place.