0

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);

2 Answers 2

1

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;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Glad to have helped :-)
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.