How do I use React state in combination with a dynamic filter component?

I have a filter component that filters a set of data. I want to output the filtered data to the DOM by using the filtered object in the local state. I cannot figure out how to use state without reseting the filter input and I can also not figure out how to output the filtered data to the DOM without using state.

This is the dataset:

const data = [
{ Name: John,
Tags: [walking, senior, Amsterdam]
},
{Name: Chris,
Tags: [biking, junior, The Hague]
},
{Name: Marc,
Tags: [walking, junior, Amsterdam]
}

I want to filter this dataset based on the tags the client selects:

<select data-categorie={hobby} onChange={filterTagHandler}>
<option value='all'>All><option>
<option value='walking'>Walking><option>
<option value='biking'>Biking><option>
<select>

<select data-categorie={age} onChange={filterTagHandler}>
<option value='all'>All><option>
<option value='junior'>Junior><option>
<option value='senior'>Senior><option>
<select>

<select data-categorie={city} onChange={filterTagHandler}>
<option value='all'>All><option>
<option value='amsterdam'>Amsterdam><option>
<option value='the hague'>The Hague><option>
<select>

The filter select components are dynamically generated from client input. Therefor there is just the filterTagHandler instead of a nameHandler, hobbyHandler, cityHandler.

First thing is to handle the selected tags and create an array from the selected tags:

const selectedTagsArray = []

    const filterTagHandler = (e) => {
        const option = e.target.options

        const tagSelected = option[option.selectedIndex].value
        const categorie = e.target.dataset.categorie

        selectedTagsArray.push(tagSelected)

        // Handle new option in categorie
        handleNewOptionInCategorie(categorie, tagSelected)

        // Handle all option
        handleAllOption(tagSelected)

        // Filter items
        filterItems(selectedTagsArray)
    }

So the first thing that happens in this onChange function is the selected tag is push to the selectedTagsArray. If I would set the selectedTagsArray to state:

const [tagsArray, setTagsArray] = useState([])

setTagsArray(selectedTagsArray)

the selectedTagsArray would be emptied every time the client selects a new filter option, because the state get’s updated. So that’s no good.

So first I use some logic to update the selectTagsArray if the client selects a new option within a categorie (select component):

const handleNewOptionInCategorie = (categorie, tagSelected) => {
        filterTags && filterTags[categorie].forEach((tag) => {
            if(selectedTagsArray.includes(tag.Tag) && tag.Tag !== tagSelected){
                const index = selectedTagsArray.indexOf(tag.Tag)
                selectedTagsArray.splice(index, 1)
            }
        })
    }

Then I handle the ‘All’ option:

const handleAllOption = (tagSelected) => {
        if(tagSelected === 'All'){
            const index = selectedTagsArray.indexOf(tagSelected)
            selectedTagsArray.splice(index, 1)
        }
    }

This all works fine (as long as there is no state change along the way).

Next I filter the data based on the selected tags:

const filterItems = (array) => {

    const newArray = []

    data.forEach(item => {

        if(array.every(tag => item.Tags.includes(tag))){
            newArray.push(item)
        }
    })
}

So this gives me the filtered data in the newArray object. The next logical step now would be to:

const [filteredItems, setFilteredItems] = useState(data)

setFilteredItems(newArray)

This has to be done inside the filteredItems object.

But I cannot use state here as well, since the filterItems function is called inside the filterTaghandler onChange and so every time the client selects a new option the state updates and the selectedTagsArray is emptied.

So, how can I use the newArray object to update the DOM or how can I use state without emptying the selectedTagsArray?