Reputation: 15
I have an action in Redux and all it does to remove the last item in a hardcoded array of 3 items.
It works fine, but I have a second property (dataLength) which calculates the length of the array. When I dispatch my action I want to remove the last item from the array and at the same time updated the array length simultaneously.
What's happening through is the item is removed the array but the length (dataLength) doesn't update till I dispatch the action again.
So I have two questions:
My dataLength property is set to null, is it possible to get the length of the array on initial state?
How do i update the dataLength propertly immediately after the first dispatch?
Thanks
REDUCER
const initialState = {
data: [
{
id: 0,
title: 'title 1'
},
{
id: 1,
title: 'title 2'
},
{
id: 2,
title: 'title 3'
}
],
dataLength: null
}
const data = (state = initialState, action) => {
switch(action.type) {
case 'DECREMENT_DATA':
return { ...state, data: state.data.filter((item) => item.id !== action.id), dataLength: state.data.length }
default:
return state;
}
}
export default data;
ACTION
export function decrement() {
return {
type: 'DECREMENT_DATA',
id: 2
}
}
COMPONENT
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { decrement } from '../actions/decrement';
class Decrement extends Component {
render() {
return (
<button onClick={this.props.decrement}>Decrement -</button>
);
}
}
const mapStateToProps = ((state) => {
return {
data: state.data
}
});
const mapDispatchToProps = ((dispatch) => {
return bindActionCreators({
decrement
}, dispatch)
});
export default connect(mapStateToProps, mapDispatchToProps)(Decrement);
Upvotes: 0
Views: 621
Reputation: 155
You should return this :
case 'DECREMENT_DATA':
const updatedArray= state.data.filter((item) => item.id !== action.id)
return { ...state, data:updatedArray , dataLength: updatedArray.length }
The reason for this is when you use state.data.length, you are still accessing old state values
Upvotes: 0
Reputation: 281606
In your reducer, you aren't correctly updating the length, since it is determined from the current state list rather than the filtered list
const data = (state = initialState, action) => {
switch(action.type) {
case 'DECREMENT_DATA':
const newList = state.data.filter((item) => item.id !== action.id)
return { ...state, data: newList, dataLength: newList.length }
default:
return state;
}
}
Upvotes: 1