I have a Component in SolidJS that looks something like this:
const MyComponent: Component = (params) => {
// ...
const [votes, setVotes] = createSignal(new Set());
const toggle = (val: string) => {
if (votes().has(val)) {
let _votes = votes();
_votes.delete(val);
setVotes(_votes);
} else {
let _votes = votes();
_votes.add(val);
setVotes(_votes);
}
}
return <>
<For each={someArray()}>{(opt, i) =>
<button
style={{
color: `${ votes().has(opt) ? "blue" : "black"}`
}}
onClick={() => { toggle(opt) } }
>
{opt()}
</button>
}</For>
</>
}
What I want to happen, is that the styling of the button will change, based on wheter it (opt in the for loop) is present in the votes set.
However, this code does not work. It doesn't update when the votes are updated.
The votes variable does update as expected.
When I give the votes set an initial value, the correct style is displayed (but it isn't updated afterwards).
Is there any solution to make this work?
What @Nick said seems to be correct, try changing your toggle method to:
const toggle = (val: string) => {
const _votes = votes();
_votes.has(val) ? _votes.delete(val) : _votes.add(val);
setVotes(new Set(_votes));
}
There is a reactive Set primitive in @solid-primitives/set that you can directly use as state without createSignal. This might simplify things for you.
Currently there are two ways to define an inline style attribute on an element:
You can use a ternary operation or other conditional expressions to create a value conditionally.
const App = () => {
const [cond, setCond] = createSignal(true);
const toggle = () => setCond(c => !c);
return (
<div onclick={toggle}>
<span>conditon: {cond() ? 'true' : 'false'}</span>
{` `}
<span
style={{ 'background-color': cond() ? 'red' : 'blue', color: 'white' }}
>
Using Object
</span>
{` `}
<span
style={`background-color: ${cond() ? 'red' : 'blue'}; color: white;`}
>
Using String
</span>
</div>
);
};
render(App, document.querySelector('#app'));
NOTE: The question is already answered but lets make it future proof by providing a general answer.