input loosing focus after each key press

Hello. I have a bug that's been bothering me for couple of days now to which I can't find any solution... Every time when I press the key in input, the text field automatically loses focus.
const [inputAnswers, setInputAnswers] = createStore<Array<string>>(
["answer1", "answer2", "answer3"]
);
const [inputAnswers, setInputAnswers] = createStore<Array<string>>(
["answer1", "answer2", "answer3"]
);
<AnswerForm
answers={inputAnswers}
onUpdateAnswer={setInputAnswers}
/>
<AnswerForm
answers={inputAnswers}
onUpdateAnswer={setInputAnswers}
/>
AnswerForm.tsx
<For each={props.answers} fallback={""}>
{(answer, index) => {
return (
<input
type="text"
value={answer}
onInput={(e) =>
props.onUpdateAnswer(index(), e.currentTarget.value)
}
/>
)}}
</For>
<For each={props.answers} fallback={""}>
{(answer, index) => {
return (
<input
type="text"
value={answer}
onInput={(e) =>
props.onUpdateAnswer(index(), e.currentTarget.value)
}
/>
)}}
</For>
Thank you for your help in advance.
5 Replies
Martnart
Martnart16mo ago
Using any primitive type array with For will result in rerendering because the array item's reference is modified. You can circumvent this by wrapping your answers in objects. { value: 'answer1' }. Now when you change the answers, the reference to the object remains stable, so it won't rerender unnecessarily. Or use Index instead of For
Alex Lohr
Alex Lohr16mo ago
Even if you don't re-render the input, another problem here is that you update answer and thus the value of the input. Whenever the value is updated, the cursor is set to the end of the input (which can be really annoying if you want to edit the value). So you can use value={/@once/answer} or value={untrack(() => answer)} to avoid that.
ArturAronov
ArturAronovOP16mo ago
Thank you! By wrapping answers into objects {value: 'answer1'} the input field keeps it focus as expected. I now have a different bug, the input value updated as expected, however on save/submit the store value remains unchanged. From the researched I've gathered, I believe it's the issue of subscribing to signal, however I couldn't find a way that actually works
Martnart
Martnart16mo ago
If Index actually works for you, I'd go with that way as it's simpler. With object entries, you'd need to make sure to actually subscribe to the signals that you want to track ( in a store all nested properties are signalified ), in this case value. By listening to just the store the changes are not picked up automatically because of the stable reference which is unchanged. Have a look at this: https://playground.solidjs.com/anonymous/9e4613f6-7901-4714-8ad7-9a1f7c91f54a Edit: make sure to adjust the store update accordingly
value={answer.value} // add 'value' to the accessor
props.onUpdateAnswer(index(), 'value', e.currentTarget.value) // add 'value' to the set store path
value={answer.value} // add 'value' to the accessor
props.onUpdateAnswer(index(), 'value', e.currentTarget.value) // add 'value' to the set store path
ArturAronov
ArturAronovOP16mo ago
Thank you so much! I managed to get it work with createStore
Want results from more Discord servers?
Add your server