0

I am new to Redux and looking for a way to remove a JSON object from an existing array in Redux. I've tried several methods but none of them worked. The code for a reducer is below:

const initialState = {serviceList: [{name: 'Ancestome', connectedAt: '08/03/2020'},{name: '23AndMe', connectedAt: '09/03/2020'},{name: 'Cancer Research UK', connectedAt: '09/03/2020'}]}


const serviceReducer = (state = initialState, action) => {
  let serviceList = [...state.serviceList]
  switch (action.type) {

    case DELETE_SERVICE:
        delete serviceList[action.id]

      return {
        ...state,   
        serviceList: serviceList
      };

    default:
      return state
  }
}

export default serviceReducer

File service.js

class Services extends React.Component {
  constructor(props) {
    super(props);
    this.addNewEle = false;
    this.state = {disabled: false};

  }

  afterAnimationComplete = () => {
        this.setState({ disabled: false });
      }


  deleteFromService = (id) => {

    this.props.deleteService(id);

    this.addNewEle = false;


    this.setState({disabled: false});
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);

  }      
      render() {

        return (
          <View style={styles.container} >
               <Header
              placement="left"
              centerComponent={{ text: 'Service', style: { color: '#fff', fontSize: 24 } }}          
             />
            <ScrollView
              ref={scrollView => this.scrollView = scrollView}
              onContentSizeChange={() => {
                this.addNewEle && this.scrollView.scrollToEnd();
              }}
            >
              <View style={{ flex: 1, padding: 4 }}>
                {Object.keys(this.props.serviceList).map((id) => {
                  return (


                    <ServiceItem
                      key={id}
                      id={id}
                      item={this.props.serviceList[id]}
                      removeItem={(id) => this.deleteFromService(id)}
                      afterAnimationComplete={this.afterAnimationComplete}
                    />
                  )
                })}
              </View>
            </ScrollView>


          </View>
        );
      }
}

const styles = StyleSheet.create(
    {
      container: {
        flex: 1,
      },
      title: {
        backgroundColor: 'transparent',
        color: 'black',
        fontSize: 24,
        paddingLeft: 10,
        paddingTop: 50,
      }
    });

  const mapStateToProps = (state) => ({ serviceList: state.serviceReducer.serviceList });

  const mapDispatchToProps = (dispatch) => ({
        deleteService: (serviceItem) => {
            dispatch(deleteService(serviceItem));
        },
    });

  export default connect(mapStateToProps, mapDispatchToProps)(Services);

In the code above, it works if I delete one entry from the array but failed for the second try. For example, I delete the first one (id = 0) then two entries remained (id = {1,2}). Now if I continue to delete the second entry (id = 1) for example, it did not delete this entry and strangely it returned two entries (id = {0,2})!!! and the similar thing occurred when I tried to remove the last entry.

I've tried the code below too:

let newList = serviceList.slice(0, action.id).concat(serviceList.slice(action.id + 1));

     return {
        ...state,   
        serviceList: newList
      };

However, if I delete the first one then it would delete the first and the last one!!!

I have no idea what was going on and would be very appreciate if someone can suggest a correct solution. Thanks

2
  • Does id represent the index of the element in the serviceList or? Commented Apr 7, 2020 at 16:30
  • 1
    Yes, 'id' represent the index of item in 'serviceList' Commented Apr 7, 2020 at 18:03

2 Answers 2

1

If id represents the index of the element in the servicesList you can than delete certain element using filter method of the array.

Your delete method would look like this then:

case DELETE_SERVICE:
  delete serviceList[action.id]

  return {
    ...state,   
    serviceList: serviceList.filter((e, index) => index !== action.id)
  };

This code will filter element which index is equal to the id from the action object.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, I've tried using filter that way too. If I print out 'serviceList' in reducer file then I can see it worked correctly but for some reason, the list had not been updated accordingly when I call function 'deleteService' in 'Service.js''
What do you mean by "the list had not been updated accordingly"? What is the new state of list after an update?
In 'service.js', I connect to Store and perform deletion operation on 'this.props.serviceList'. For some reason, everything happens on the store did not get updated in 'this.props.serviceList'. For example, after deleting the second entry, the size of 'serviceList' in reducer was 1 while 'this.props.serviceList.length' was 2 meaning that nothing get deleted. Something must have been wrong here that I could not figure it out.
0

Thanks everyone. I've found out that there had been a problem with my animated list view rather than the issue with reducer itself. The issue is closed now.

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.