How do i make a list properly reactive to state changes?
So I have this for loops that iterates in an array of data fetched on page load,
i devided the sorting functions in 2 categories checkerFunctions that check a checkbox value, and filterFunctions that check a object value in a signal.
The filterFunctions steps works just fine, but i don't know why the checkFunctions don't.
Am i assigning a bool wrongfully?
const checkerFunctions = {
NotUserCreator: item => item.Creator.Id == userId,
};
const filterFunctions = {
robux: item => {
return item.Product.PriceInRobux >= activeFilters().robux.min && item.Product.PriceInRobux <= activeFilters().robux.max;
},
};
const [activeFilters, setActiveFilters] = createSignal({
...Object.fromEntries(
Object.entries(checkerFunctions).map(([key]) => {
return [key, false];
}),
),
robux: { min: 0, max: Infinity },
NotUserCreator: false,
});
const FiltersComponent = () => (
<div>
<h2>Filters:</h2>
<hr />
{Object.keys(checkerFunctions).map(key => {
return (
<div>
<input type='checkbox' checked={activeFilters()?.[key]} onChange={() => setActiveFilters(pre => ({ ...pre, [key]: !pre[key] }))} />
<label for={key}>{key}</label>
</div>
);
})}
<h2>Robux</h2>
<div>
<div>
<label>Min:</label>
<input
onInput={e => {
numericInput(e);
setActiveFilters(pre => ({ ...pre, robux: { max: pre.robux.max, min: Number(e.currentTarget.value) } }));
if (!e.target.value) {
setActiveFilters(pre => ({ ...pre, robux: { max: pre.robux.max, min: 0 } }));
}
}}
/>
</div>
<div>
<label>Max:</label>
<input
onInput={e => {
numericInput(e);
setActiveFilters(pre => ({ ...pre, robux: { min: pre.robux.min, max: Number(e.currentTarget.value) } }));
if (!e.target.value) {
setActiveFilters(pre => ({ ...pre, robux: { min: pre.robux.min, max: Infinity } }));
}
}}
/>
</div>
</div>
</div>
);
const checkerFunctions = {
NotUserCreator: item => item.Creator.Id == userId,
};
const filterFunctions = {
robux: item => {
return item.Product.PriceInRobux >= activeFilters().robux.min && item.Product.PriceInRobux <= activeFilters().robux.max;
},
};
const [activeFilters, setActiveFilters] = createSignal({
...Object.fromEntries(
Object.entries(checkerFunctions).map(([key]) => {
return [key, false];
}),
),
robux: { min: 0, max: Infinity },
NotUserCreator: false,
});
const FiltersComponent = () => (
<div>
<h2>Filters:</h2>
<hr />
{Object.keys(checkerFunctions).map(key => {
return (
<div>
<input type='checkbox' checked={activeFilters()?.[key]} onChange={() => setActiveFilters(pre => ({ ...pre, [key]: !pre[key] }))} />
<label for={key}>{key}</label>
</div>
);
})}
<h2>Robux</h2>
<div>
<div>
<label>Min:</label>
<input
onInput={e => {
numericInput(e);
setActiveFilters(pre => ({ ...pre, robux: { max: pre.robux.max, min: Number(e.currentTarget.value) } }));
if (!e.target.value) {
setActiveFilters(pre => ({ ...pre, robux: { max: pre.robux.max, min: 0 } }));
}
}}
/>
</div>
<div>
<label>Max:</label>
<input
onInput={e => {
numericInput(e);
setActiveFilters(pre => ({ ...pre, robux: { min: pre.robux.min, max: Number(e.currentTarget.value) } }));
if (!e.target.value) {
setActiveFilters(pre => ({ ...pre, robux: { min: pre.robux.min, max: Infinity } }));
}
}}
/>
</div>
</div>
</div>
);
1 Reply
The rendering:
I removed types in the first code cuz i couldn't paste for the limit
<For
each={data()?.Data.Items.filter(item => {
const conditions: boolean[] = [];
for (const [key, value] of Object.entries(activeFilters())) {
reRenders++;
console.log(key, value);
if (typeof value == 'boolean') {
conditions.push(checkerFunctions[key](item));
} else if (typeof value == 'object') {
conditions.push(filterFunctions[key](item));
}
}
return conditions.every(Boolean);
})}
>
//...
<For
each={data()?.Data.Items.filter(item => {
const conditions: boolean[] = [];
for (const [key, value] of Object.entries(activeFilters())) {
reRenders++;
console.log(key, value);
if (typeof value == 'boolean') {
conditions.push(checkerFunctions[key](item));
} else if (typeof value == 'object') {
conditions.push(filterFunctions[key](item));
}
}
return conditions.every(Boolean);
})}
>
//...