Home > Software engineering >  SolidJS -- How to make DOM elements reactive to signal updates?
SolidJS -- How to make DOM elements reactive to signal updates?

Time:09-09

Novice Question -- Using SolidJS, how do I make DOM elements reactive to signal updates?

I have two instances which I cannot get to update as expected.

  1. Within the Origin Component, when attempting to update the item count.
  2. Within Remote Component, when attempting to update the item results.

Origin Component

import { Component } from 'solid-js'
import { isEqual as _isEqual } from 'lodash-es'

const [getItems, setItems] = createSignal<Array<Item>>([])

const OriginComponent: Component = () => {
    const updateItems = (item: Item) => {
        const init = getItems()
        const index = init.findIndex(i => _isEqual(i, item))

        index == -1 ? init.push(item) : init.splice(index, 1)

        setItems(init)
    }

    return (
        <>
            <span>Item Count: {getItems().length}</span> //       << -- WILL NOT CHANGE.
            <button onclick={() => updateItems(x: Item)}>Click Me</button>
        </>
    )
}

export { OriginComponent, getItems }

Remote Component

import { Component } from 'solid-js'
import { getItems } from '../OriginComponent'

const RemoteComponent: Component = () => {
    return (
        <p class='results'>
            {getItems() ? 'Has Items' : 'Has No Items'} //        << -- WILL NOT CHANGE.
        </p>
    )
}

CodePudding user response:

According to Solid's API docs for createSignal (in the options section):

By default, when calling a signal's setter, the signal only updates (and causes dependents to rerun) if the new value is actually different than the old value, according to JavaScript's === operator.

This is the case here, as the array you are setting in the signal is the same (===) as the old one. One workaround is to set turn off referential equality checks for the signal, like so: createSignal<Array<Item>>([], { equals: false }).

Another option is to create a new array when setting the array again, like so: setItems([...init])

  • Related