Solid doesn't re-render when update the same array in createSignal

Expected behavior: Re-render inputs every time passwords array is updated even with the same value, to avoid duplicating value in the same input.
import { Component, For, createSignal } from 'solid-js'

const App: Component = () => {
const [passwords, setPasswords] = createSignal(['', '', ''])

const setPassword = (v: string, index: number) => {
const value = v.split('').reverse()[0]

setPasswords(old =>
old.map((oldValue, currentIdx) => {
if (currentIdx === index) return value

return oldValue
})
)
}

return (
<For each={passwords()}>
{(v, idx) => {
console.log('render the inputs')

return (
<input
type="number"
min="0"
max="9"
step="1"
maxLength="1"
value={v}
onInput={e => setPassword(e.target.value, idx())}
/>
)
}}
</For>
)
}

export default App
import { Component, For, createSignal } from 'solid-js'

const App: Component = () => {
const [passwords, setPasswords] = createSignal(['', '', ''])

const setPassword = (v: string, index: number) => {
const value = v.split('').reverse()[0]

setPasswords(old =>
old.map((oldValue, currentIdx) => {
if (currentIdx === index) return value

return oldValue
})
)
}

return (
<For each={passwords()}>
{(v, idx) => {
console.log('render the inputs')

return (
<input
type="number"
min="0"
max="9"
step="1"
maxLength="1"
value={v}
onInput={e => setPassword(e.target.value, idx())}
/>
)
}}
</For>
)
}

export default App
F
foolswisdom43d ago
This is the default behavior. If you want to change it, pass { equals: false } as the second option of createSignal. See https://docs.solidjs.com/reference/basic-reactivity/create-signal
Z
Zwel43d ago
I tried {equal: false}, but result is the same. Not re-render every time.
T
thetarnav43d ago
wrap each string in an object so that For can compare unique references right now it compares strings, because those are the items, where they are compared by value, which can have undefined behaviors like this or use Index if you don’t plan on reordering the passwords
M
Maciek5032243d ago
so it doesn't rerender because of this:
const value = v.split('').reverse()[0]
const value = v.split('').reverse()[0]
which btw can be rewritten as
const value = v.at(-1) ?? ""
const value = v.at(-1) ?? ""
then you set this value to your signal. Renders for lists in For / Index are triggered when reference / value changes, so something like from your example with
passwords().map((v, idx) => <>...<>) // ❌ avoid this
passwords().map((v, idx) => <>...<>) // ❌ avoid this
should work, but would be very inefficient, as every element would be recreated each time 1 value changes. My suggestion is to: - set input value by reference to the input after you change it - consider using stores for nested objects, it just have nicer syntax and reacts to only signle element that changed - use rather Index than For when the enumerating value is primitive (not an object) So finally something like this
const [passwords, setPasswords] = createStore(["", "", ""]);
let inputs: HTMLInputElement[] = [];
const setPassword = (v: string, index: number) => {
const value = v.at(-1) ?? "";
setPasswords(index, value); //clean syntax isn't it? :)
inputs[index].value = value; // update input directly yourself
//...
};
return <Index each={passwords}> //Index instead of For
{(v, idx) => {
console.log("render the inputs");

return (
<>
<input
ref={inputs[idx]} // new
...
value{v()} // v() instead of v
onInput={(e) => setPassword(e.target.value, idx)} // idx instead of idx()
/>
</>
);
}}
</Index>
const [passwords, setPasswords] = createStore(["", "", ""]);
let inputs: HTMLInputElement[] = [];
const setPassword = (v: string, index: number) => {
const value = v.at(-1) ?? "";
setPasswords(index, value); //clean syntax isn't it? :)
inputs[index].value = value; // update input directly yourself
//...
};
return <Index each={passwords}> //Index instead of For
{(v, idx) => {
console.log("render the inputs");

return (
<>
<input
ref={inputs[idx]} // new
...
value{v()} // v() instead of v
onInput={(e) => setPassword(e.target.value, idx)} // idx instead of idx()
/>
</>
);
}}
</Index>
Also there's other way, without ref and updating input value yourself. It's to pass a signal that does trigger when you set it, that is: example with signal & For
<input
value={passwords()[idx()]}
...
/>
<input
value={passwords()[idx()]}
...
/>
for store & Index I have no better idea yet than that:
const setPassword = (v: string, index: number) => {
const value = v.at(-1) ?? "";
batch(() => {
setPasswords(index, "");
setPasswords(index, value);
});
};
...
<input
value={passwords[idx]}
...
/>
const setPassword = (v: string, index: number) => {
const value = v.at(-1) ?? "";
batch(() => {
setPasswords(index, "");
setPasswords(index, value);
});
};
...
<input
value={passwords[idx]}
...
/>
because store also trigger change only when value is different, that's why I set passwords value to "" then to desired value. Wrapped in batch, so that first set to "" doesn't trigger anything - without batch input value would change to "" then to desired value but very quickly, this way it changes directly to desired value and is notified that it changed, even though it didn't
Z
Zwel42d ago
@Maciek50322 Thank you for your clarifying. It helps me a lot.
Want results from more Discord servers?
Add your server
More Posts
For some reason <select> doesn't work correctlyhttps://playground.solidjs.com/anonymous/eedf65f3-e52b-49b0-a8b2-513465a75666 Here it is. When changCan someone tell me how to redirect the user on each API, if 401, that is, do not write the logic agCan someone tell me how to redirect the user on each API, if 401, that is, do not write the logic agHow to use web component in solidjsPlease ask solidjs how to solve the use of web component component editor ts reported error PropertyHow do I debug updatesI thought My app is working fine except I noticed a lag, which performance profile shows lots of unnHow to detect button holding in solid js?Does anyone know how to detect a button being holding for 2 seconds and are there any libraries or bVite internal server error expected "}" but found end of filesee screenshot, this is not the end of the file (not even close)How do I "curry" a function with props?I have a method "colorize" that receives two arguments: hue and shade. A component has a props.hue aMobX + SolidJS enableExternalSource untracked bug?I am evaluating using MobX with SolidJS and now that there is an `untrack` parameter to `enableExterhow to efficiently make nested data structures in solidHello, I am new to Solid atm, but am aware of some reactivity principles like singals, memos, effectSolidStart - Nitro Module missing `context` keys in `request`Hey guys, I understand what I am asking about is likely out of scope, as this is dealing with a 3rHandle user interactions to send backendI would like to know what are methods that can handle identification of user interaction points likeHow do I use solid for reactivity without a build step?I like solid as a frontend library, and I want to use it as a "vanilla" state management library foruse directive typescript errorWhen i try to use the use: directive i get the error ```Type '{ type: string; placeholder: string; vI have to fetch initial information in a component, how do I do it?const App: Component = () => { const resp = await fetch(...); // show Home component after fDynamically creating resources based on reactive state in Solid Store**What would be the right approach to solve this using solids reactivity? ** I want to achieve the Struggling to understand the correct way to use createResource with a storeI have a global store `export const [dataStore, setDataStore] = createStore({ some: "data"}) `, whicHow do I "protect" routes? I am using @solidjs/routerNow that Outlet is not supported anymore? How do I implement a route guard for nested routes?What are canonical patterns to separate UI from domain logic in SolidJS?I am developing an app that helps guitarists to learn notes. Users learn notes by exercising. The exsolidjs createResource doesn't show error when there was an error i.e 401 Invalid credentialscreateResource data.error always falsesomeone used the plugin postcss-functions ?how to set the visibility of functions in css files. ide shows that there is an unknown function, wh