The initial state of the store is:
let initialState = {
items: [],
itemsCount: 0,
pletedCount: 0
};
When I dispatch an action with the type ADD_ITEM
the new item is added to the items
array and itemsCount
is incremented (Although I'm not sure if I'm doing it correctly)
case "ADD_ITEM": {
return {
...state,
items: [
...state.items,
{
title: action.name,
dateCreated: action.date,
id: action.id,
isChecked: false
}
],
itemsCount: state.items.length + 1
};
}
and for TOGGLE_ITEM
case "TOGGLE_ITEM": {
return Object.assign({}, state, {
items: state.items.map(item => {
if (item.id !== action.id) {
return item;
}
return Object.assign({}, item, {
isChecked: !item.isChecked
});
})
});
}
When I dispatch an action with the type REMOVE_ITEM
the following is executed:
case "REMOVE_ITEM": {
return Object.assign({}, state, {
items: [...state.items.filter(item => item.id !== action.id)],
itemsCount: state.items.length - 1
});
}
Now I'm trying to count the items that have isChecked
is true
state.items.map(item => {
if(item.isChecked){
//Increment count
}
})
I'm not sure where exactly to do that.
Inside the TOGGLE_ITEM
action?
Inside a new COUNT_ITEM
action? if so, when is that action dispatched?
And how do assign an incremented digit to part of the state?
The initial state of the store is:
let initialState = {
items: [],
itemsCount: 0,
pletedCount: 0
};
When I dispatch an action with the type ADD_ITEM
the new item is added to the items
array and itemsCount
is incremented (Although I'm not sure if I'm doing it correctly)
case "ADD_ITEM": {
return {
...state,
items: [
...state.items,
{
title: action.name,
dateCreated: action.date,
id: action.id,
isChecked: false
}
],
itemsCount: state.items.length + 1
};
}
and for TOGGLE_ITEM
case "TOGGLE_ITEM": {
return Object.assign({}, state, {
items: state.items.map(item => {
if (item.id !== action.id) {
return item;
}
return Object.assign({}, item, {
isChecked: !item.isChecked
});
})
});
}
When I dispatch an action with the type REMOVE_ITEM
the following is executed:
case "REMOVE_ITEM": {
return Object.assign({}, state, {
items: [...state.items.filter(item => item.id !== action.id)],
itemsCount: state.items.length - 1
});
}
Now I'm trying to count the items that have isChecked
is true
state.items.map(item => {
if(item.isChecked){
//Increment count
}
})
I'm not sure where exactly to do that.
Inside the TOGGLE_ITEM
action?
Inside a new COUNT_ITEM
action? if so, when is that action dispatched?
And how do assign an incremented digit to part of the state?
Share Improve this question edited May 8, 2018 at 6:30 Zakher Masri asked May 8, 2018 at 6:18 Zakher MasriZakher Masri 1,1861 gold badge17 silver badges21 bronze badges3 Answers
Reset to default 4You can just pute it when you need it in your actions/ponents etc:
items.filter(item => item.isChecked).length
It's not a good practice to store derived values such as the count of certain items (including the itemsCount
variable) in your state (reasons similar to why you normalise your state).
If you are worried about performance (it's O(n) so shouldn't be much of an issue in general), you can use a memoization library.
The count needs to be recalculated on TOGGLE_ITEM
as well as ADD/REMOVE_ITEM
. And the count reducer could use reduce like
state.items.reduce((acc, item) => {
if(item.isChecked){
acc += 1;
}
return acc;
}, 0)
However, you are better of not storing the COUNT in the reducer since it is directly derivable from items, you can simply calculate the count using a memoized selector
in your mapStateToProps
function. You could make use of reselect
for writing memoized selectors or create your own
Just a quick note, in order to reduce the extra overhead in your action code:
case "ADD_ITEM": {
let items=state.items
items.push({
title: action.name,
dateCreated: action.date,
id: action.id,
isChecked: false
})
return {
...state,
items: items,
itemsCount: state.itemsCount+1
};
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744794523a4594124.html
评论列表(0条)