blakebullwinkel
blakebullwinkel

Reputation: 335

Unable to delete items in React Native FlatList

I am unable to get the delete button on a custom component called ActivityItem to work.

Custom component in ActivityItem.js:

const ActivityItem = props => {
    return (
        <View>
            <Button title="Delete" onPress={props.onDelete} />
        </View>
    );
};

removeActivity function defined in the activities.js actions file:

export const REMOVE_ACTIVITY = 'REMOVE_ACTIVITY';

export const removeActivity = id => {
    return {type: REMOVE_ACTIVITY, id: id};
};

And my activities.js reducer file:

const initialState = {
    allActivities: ACTIVITIES,
    userActivities: ACTIVITIES.filter(activity => activity.userId === 'u1')
};

export default (state = initialState, action) => {
    REMOVE_ACTIVITY:
        const updatedUserActivities = state.userActivities.filter((activity) => activity.id !== action.id);
        return {
            ...state,
            userActivities: updatedUserActivities
        };
    return state;
};

ACTIVITIES is a list of Activity items which contain userId and unique id properties.

Finally, the screen where I render a FlatList:

const MyScreen = props => {
    const myActivities = useSelector(state => state.activities.userActivities);
    const dispatch = useDispatch();
    return (
        <FlatList 
            data={myActivities}
            keyExtractor={item => item.id}
            renderItem={itemData => (
                <ActivityItem 
                    onDelete={() => {
                        dispatch(removeActivity(itemData.item.id));
                    }} 
                />
            )}
        />
    );
};

Can anyone tell me what I'm doing wrong here?

Upvotes: 0

Views: 350

Answers (3)

blakebullwinkel
blakebullwinkel

Reputation: 335

For anyone who is struggling with a similar issue, make sure you are importing your action in the reducer file correctly.

Originally, I was importing like this:

import REMOVE_ACTIVITY from '../actions/activities';

Adding curly braces like this fixed the issue.

import { REMOVE_ACTIVITY } from '../actions/activities';

Upvotes: 0

jamal
jamal

Reputation: 1105

You need to change your reducer like this

const initialState = {
    allActivities: ACTIVITIES,
    userActivities: ACTIVITIES.filter(activity => activity.userId === 'u1')
};
export default (state = initialState, action) => {
    REMOVE_ACTIVITY:
        const updatedUserActivities = state.userActivities.filter((activity) => activity.id !== action.id);
        return {
            ...state,
            userActivities: [...updatedUserActivities]
        };
    return state;
};

you need to add extraData props to flatList, like given below for reflecting changes in flatList

const MyScreen = props => {
    const myActivities = useSelector(state => state.activities.userActivities);
    const dispatch = useDispatch();
    return (
        <FlatList 
            data={myActivities}
            extraData={myActivities}
            keyExtractor={item => item.id}
            renderItem={itemData => (
                <ActivityItem 
                    onDelete={() => {
                        dispatch(removeActivity(itemData.item.id));
                    }} 
                />
            )}
        />
    );
};

Upvotes: 1

Akshay Rao
Akshay Rao

Reputation: 3544

As far as I can see you need to make changes in your reducer file, that seems faulty to me. Although not much could be said by just looking at this small piece of code. I'll suggest to make changes in your reducer file so that it should look something like below:-

export default (state = initialState, action) => {
  const { type, id } = action;

  switch (type) {
    case REMOVE_ACTIVITY:
      const { userActivities } = state.activities || {};
      const updatedUserActivities = userActivities.filter((activity) => activity.id !== id);
      console.log('updatedUserActivities is', updatedUserActivities, ' and userActivities is', userActivities);     // can use this console to check the values before updating.
      return {
          ...state,
          userActivities: updatedUserActivities,
      };
    default:
      return state;
  }
};

Things changed in your reducer file was:-

  • Used userActivities from the correct place i.e. state.activities instead of directly from the state.
  • Corrected the switch case which works.

As suggested above in the code if you want to look what reducer is trying to update please try and print the updatedUserActivities and the value of userActivities. I hope this would fix your issue, Enjoy!

Upvotes: 0

Related Questions