Joe Consterdine
Joe Consterdine

Reputation: 15

Redux Dispatch - Remove Item from Array / Incorrect array length output

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:

  1. My dataLength property is set to null, is it possible to get the length of the array on initial state?

  2. 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

Answers (2)

anurag145
anurag145

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

Shubham Khatri
Shubham Khatri

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

Related Questions