So I have the following code in SolidJS.
I am using createSignal
and I want to render certain views when the values in options
changes.
import { render } from "solid-js/web";
import { createSignal, Show, Index } from "solid-js";
const options = [
{
title: "ReactJs",
subtitle: "A front-end framework for building views on the web",
selected: false
},
{
title: "SolidJS",
subtitle: "Lorem, ipsum dolor sit amet consectetur adipisicing.",
selected: false
},
{
title: "MumboJumboJS",
subtitle: "null",
selected: false
}
]
export default function CheckboxArea(props) {
const [options, setOptions] = createSignal(props.options);
console.log(options())
function onClickListener(index: number) {
console.log("Click")
const op = options()
op[index].selected = true
setOptions(op)
}
return(
<div>
<Index each={options()}>{(each_option, index) =>
<div onClick={() => onClickListener(index)}>
<Show when={options()[index].selected}>
<div>{each_option().title}</div>
</Show>
<Show when={!options()[index].selected}>
<div>{each_option().subtitle}</div>
</Show>
</div>
}
</Index>
</div>
)
}
render(() => <CheckboxArea options={options}/>, document.getElementById("app")!);
Of course click events register and options()
updates but the views do not.
You are trying to mutate an existing value and setting it back as the new value. However signals run equality checks internally, since you are passing the same value, because arrays are objects and objects are compared by reference, signal's value is never updated.
There are several solutions, most basic one is create a new array with updated values and set it as the new value:
function onClickListener(index: number) {
setOptions([...updatedList]);
}
Alternatively you can set equals to false on the signal, so to force an update even if the value is same.
createSignal(props.options, { equals: false });