snippetjavascriptMinor
Redux reducer with a filter
Viewed 0 times
reducerfilterwithredux
Problem
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
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
Solution
Well, you could use
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
So:
It's good to keep the
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) => {
return filterKeys.reduce((acc, key) => acc && launch[key] === filter[key], true)
});
}
// Then in the component
import { filterLaunches } from '../launchesStore';
const LaunchesList = ({launches, filter}) => (
{filterLaunches(launches, filter).map((launch) => (
Launch: {launch.name}
))}
);
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.Code Snippets
...
case 'filterLaunches':
return Object.assign({}, state, {
filteredLaunches: state.launches.filter(function(launch) {
return action.location === launch.location.countryCode
})
}
default:
return state;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) => {
return filterKeys.reduce((acc, key) => acc && launch[key] === filter[key], true)
});
}
// Then in the component
import { filterLaunches } from '../launchesStore';
const LaunchesList = ({launches, filter}) => (
<ul>
{filterLaunches(launches, filter).map((launch) => (
<li>Launch: {launch.name}</li>
))}
</ul>
);
export default connect(LaunchesList);Context
StackExchange Code Review Q#156970, answer score: 5
Revisions (0)
No revisions yet.