I am trying to create an application using React Js, basically the application consists of a series of filters which have a unique value each one, based on the selected elements a text string is created to fetch a specific file, to each filter I have assigned a variable to identify the id of the currently selected button. Sometimes the appearance of a filter depends on another one and the filtering options are not always the same. In the simple cases the program works but when I make complex query I have a problem because I can’t return the value of the variable assigned to a filter to “-1” or something undefined so that it doesn’t interfere in the text string that searches the file.
I am open to any suggestions for implementation, additionally I add an image of how the filters look like.

for example if I select one of the buttons on the first line which would be a filter, the id value of the third and fourth filter should revert to -1 since based on the options above something can change below and each option has a unique id
What I have tried is to create a component called FilterGroup which is composed of other CustomButton components, the first component is filled according to an array of options that are passed as props. Next I leave the code of each one, and the code of App.jsx
(I know I should refactor it)
import { useEffect, useState, useCallback } from 'react'
import Board from './components/Board'
import Filter from './components/Filter'
import './App.css'
import {
initialStackOptions,
positionOptions,
initialSequenceOptions,
tooltipOptions,
extraActionsOptions,
thirdOptions,
leftPositionOptions,
rightPositionOptions,
actionStackOptions
} from './constants';
function App() {
// Sequence
const [playerSequenceFilterId, setPlayerSequenceFilterId] = useState(0)
// Position
const [leftPositionFilterId, setLeftPositionFilterId] = useState(10)
const [rightPositionFilterId, setRightPositionFilterId] = useState(-1)
// Extra action usually
const [thirdFilterId, setThirdFilterId] = useState(-1)
// Opponnent position for extra action
const [secondLeftPositionFilterId, setSecondLeftPositionFilterId] = useState(-1)
const [secondRightPositionFilterId, setSecondRightPositionFilterId] = useState(-1)
// Extra action 2
const [fifthFilterId, setFifthFilterId] = useState(-1)
//Last position for extra action 2
const [thirdLeftPositionFilterId, setThirdLeftPositionFilterId] = useState(-1)
const [thirdRightPositionFilterId, setThirdRightPositionFilterId] = useState(-1)
// Our Effective stack
const [effectiveStackFilterId, setEffectiveStackFilterId] = useState(5)
// Action stack
const [actionStackFilterId, setActionStackFilterId] = useState(-1)
const [data, setData] = useState({})
const getTooltipValueById = (id) => tooltipOptions.find((option) => option.id === id)?.value || '';
const getLeftPositionOptions = () => {
if (playerSequenceFilterId === 0) return leftPositionOptions["9000000"]
else if (playerSequenceFilterId === 1) return leftPositionOptions["9000001"]
}
const getRightPositionOptions = () => {
if (playerSequenceFilterId === 1) return rightPositionOptions["9000001"]
}
const getThirdOptions = () => {
if (playerSequenceFilterId === 0 && leftPositionFilterId === 10) return thirdOptions["9000000"]
else if (playerSequenceFilterId === 0 && [11, 12, 13, 14].includes(leftPositionFilterId)) return thirdOptions["9000001"]
else if (playerSequenceFilterId === 1) return thirdOptions["9000002"]
else if (playerSequenceFilterId === 2 && leftPositionFilterId === 15 && [10, 11, 12, 13, 14].includes(rightPositionFilterId)) return thirdOptions["9000003"]
else if (playerSequenceFilterId === 2 && [10, 11, 12, 13].includes(leftPositionFilterId) && [11, 12, 13, 14].includes(rightPositionFilterId)) return thirdOptions["9000004"]
}
const queryFilename = useCallback(() => {
let string = ''
const playerSequenceValue = initialSequenceOptions.find((option) => option.id === playerSequenceFilterId)?.value || ''
const leftPositionValue = positionOptions.find((option) => option.id === leftPositionFilterId)?.value || ''
const rightPositionValue = positionOptions.find((option) => option.id === rightPositionFilterId)?.value || ''
const thirdFilterValue = extraActionsOptions.find((option) => option.id === thirdFilterId)?.value || ''
const secondLeftPositionValue = positionOptions.find((option) => option.id === secondLeftPositionFilterId)?.value || ''
const secondRightPositionValue = positionOptions.find((option) => option.id === secondRightPositionFilterId)?.value || ''
const fifthFilterValue = extraActionsOptions.find((option) => option.id === fifthFilterId)?.value || ''
const thirdLeftPositionValue = positionOptions.find((option) => option.id === thirdLeftPositionFilterId)?.value || ''
const thirdRightPositionValue = positionOptions.find((option) => option.id === thirdRightPositionFilterId)?.value || ''
const effectiveStackValue = initialStackOptions.find((option) => option.id === effectiveStackFilterId)?.value || ''
const actionStackValue = initialStackOptions.find((option) => option.id === actionStackFilterId)?.value || ''
const variables = [
playerSequenceValue,
leftPositionValue,
rightPositionValue,
thirdFilterValue,
secondLeftPositionValue,
secondRightPositionValue,
fifthFilterValue,
thirdLeftPositionValue,
thirdRightPositionValue,
effectiveStackValue,
actionStackValue,
]
const numberOfNonEmptyValues = variables.filter((value) => value !== '').length
switch (playerSequenceFilterId) {
case 0:
switch (numberOfNonEmptyValues) {
case 3:
string += `${playerSequenceValue}-${leftPositionValue}-${effectiveStackValue}`
break
case 6:
string += `${playerSequenceValue}-${leftPositionValue}-${thirdFilterValue}-${secondLeftPositionValue}-${effectiveStackValue}-${actionStackValue}`
break
case 7:
string += `${playerSequenceValue}-${leftPositionValue}-${thirdFilterValue}-${secondLeftPositionValue}.${secondRightPositionValue}-${effectiveStackValue}-${actionStackValue}`
break
case 8:
string += `${playerSequenceValue}-${leftPositionValue}-${thirdFilterValue}-${secondLeftPositionValue}-${fifthFilterValue}-${thirdLeftPositionValue}-${effectiveStackValue}-${actionStackValue}`
break
case 10:
string += `${playerSequenceValue}-${leftPositionValue}-${thirdFilterValue}-${secondLeftPositionValue}.${secondRightPositionValue}-${fifthFilterValue}-${thirdLeftPositionValue}.${thirdRightPositionValue}-${effectiveStackValue}-${actionStackValue}`
break
}
break
}
string += '.json'
return string
}, [
playerSequenceFilterId,
leftPositionFilterId,
rightPositionFilterId,
thirdFilterId,
secondLeftPositionFilterId,
secondRightPositionFilterId,
fifthFilterId,
thirdLeftPositionFilterId,
thirdRightPositionFilterId,
effectiveStackFilterId,
actionStackFilterId
])
useEffect(() => {
const filename = queryFilename()
fetch(`./micro_stakes/${filename}`)
.then(res => res.json())
.then(json => setData(json))
.catch(err => console.log(err))
}, [
queryFilename,
playerSequenceFilterId,
leftPositionFilterId,
rightPositionFilterId,
thirdFilterId,
secondLeftPositionFilterId,
secondRightPositionFilterId,
fifthFilterId,
thirdLeftPositionFilterId,
thirdRightPositionFilterId,
effectiveStackFilterId,
actionStackFilterId
])
let actionStack = (playerSequenceFilterId === 0 && leftPositionFilterId !== -1 && (rightPositionFilterId,
thirdFilterId,
secondLeftPositionFilterId,
secondRightPositionFilterId,
fifthFilterId,
thirdLeftPositionFilterId,
thirdRightPositionFilterId,
actionStackFilterId) === -1) ? true : false
return (
<>
<h2>Preflop Helper</h2>
<div className="filters">
<Filter
header={getTooltipValueById(1000000) || ''}
options={initialSequenceOptions}
updateSelectedId={setPlayerSequenceFilterId}
selectedId={playerSequenceFilterId}
doSomethingAfterClick={queryFilename}
identificator='playerSequence'
strict={true}
/>
{
initialSequenceOptions[playerSequenceFilterId]?.positionDouble ? (
<>
<Filter
header={initialSequenceOptions[playerSequenceFilterId]?.headersPositionDouble[0].value}
options={getLeftPositionOptions() || []}
updateSelectedId={setLeftPositionFilterId}
selectedId={leftPositionFilterId}
doSomethingAfterClick={queryFilename}
identificator='firstPosition'
strict={true}
/>
<Filter
header={initialSequenceOptions[playerSequenceFilterId]?.headersPositionDouble[1].value}
options={getRightPositionOptions() || []}
updateSelectedId={setRightPositionFilterId}
selectedId={rightPositionFilterId}
doSomethingAfterClick={queryFilename}
identificator="secondPosition"
strict={true}
/>
</>
) : (
<Filter
header={initialSequenceOptions[playerSequenceFilterId]?.headerPositionUnique.value}
options={getLeftPositionOptions() || []}
updateSelectedId={setLeftPositionFilterId}
selectedId={leftPositionFilterId}
doSomethingAfterClick={queryFilename}
identificator='firstPosition'
strict={false}
/>
)
}
<Filter
header={initialSequenceOptions[playerSequenceFilterId]?.headerThirdFilter.value}
options={getThirdOptions() || []}
updateSelectedId={setThirdFilterId}
selectedId={thirdFilterId}
doSomethingAfterClick={queryFilename}
identificator='thirdFilter'
strict={false}
/>
{
thirdFilterId !== -1 ? (
<>
<Filter
header={getTooltipValueById(1000008)}
options={positionOptions || []}
updateSelectedId={setSecondLeftPositionFilterId}
selectedId={secondLeftPositionFilterId}
doSomethingAfterClick={queryFilename}
identificator='thirdFilter'
strict={false}
/>
</>
) : (
<></>
)
}
<Filter
header={getTooltipValueById(1000002) || ''}
options={initialStackOptions}
updateSelectedId={setEffectiveStackFilterId}
selectedId={effectiveStackFilterId}
doSomethingAfterClick={queryFilename}
identificator='effectiveStack'
strict={true}
/>
{
actionStack ? (
<></>
) : (
<Filter
header={getTooltipValueById(1000007) || ''}
options={actionStackOptions}
updateSelectedId={setActionStackFilterId}
selectedId={actionStackFilterId}
doSomethingAfterClick={queryFilename}
identificator='actionStack'
strict={true}
/>
)
}
</div>
<Board data={data}/>
</>
)
}
export default App