Michi YC
Michi YC

Reputation: 5

Can't use array functions like .includes in Object literals

I'm trying to organise my react state in object literals consisting of arrays.

const [state, setState] = React.useState({ filter: [], other: [] });

I want to update my filter array, whenever a click on a list item occurs.

    const handleListItemClick = (event, index) => {
    if (state['filter'].includes(index)) {
        setState(state['filter'].filter(function (element) {
            return element != index;
        }))
    } else {
        setState(state['filter'].concat([index]));
    }
};

But whenever I try to access the filter array, java script can't resolve array functions like includes or indexOf, for instance:

<ListItem
          button
          selected={state['filter'].includes(0)}
          onClick={(event) => handleListItemClick(event, 0)}>
                <ListItemText primary="Kundensegmente" />
</ListItem

I get this error:

Uncaught TypeError: state.filter.includes is not a function

Using functions like includes seems to work in one-dimensional arrays.

Upvotes: 0

Views: 129

Answers (1)

Quentin
Quentin

Reputation: 943579

The original shape of the state was this:

{ filter: [], other: [] }

But then you changed it:

setState(state['filter'].concat([index]));

You replaced the whole state with the value of fiter (an empty array) concatinated with a new array [index].

That new array doesn't have a filter property.


Use separate states for filter and other.

const [filter, setFilter] = React.useState([]);
const [other, setOther] = React.useState([]);

Alternatively, if you really want to keep them merged into a single object, then you need to maintain the shape of that object in the state.

Create a new object which is the same as the old object except for just the bits you want to change.

setState({
    ...state,
    filter: state.filter.concat([index]);
});

Upvotes: 4

Related Questions