Closed Geordi7 closed 2 years ago
After further testing it seems the problem is not with the input itself but with the text node before it.
if you replace Hello {s.a.b.c}<br />
with {'Hello ' + s.a.b.c}<br />
it works correctly.
This is probably still a bug.
@Geordi7 It seems the first approach causes the entire parent div
to refresh, which wipes out the input
element, killing the focus. Wrapping it in a span
so it has its own node also seems to resolve the issue.
const focus = e => e.focus();
class C extends Component {
state = {a: {b: {c: ''}}}
view = s => <div>
<span>Hello {s.a.b.c}</span>
<input type='text' value={s.a.b.c}
$oninput={(s,e) => (s.a.b.c=e.target.value, s)}
/>
</div>
}
new C().start(document.body)
Another solution might be to use a ref
so it's refocused when the input
element is refreshed:
const focus = e => e.focus();
class C extends Component {
state = {a: {b: {c: ''}}}
view = s => <div>
Hello {s.a.b.c}<br/>
<input ref={focus} type='text' value={s.a.b.c}
$oninput={(s,e) => (s.a.b.c=e.target.value, s)}
/>
</div>
}
new C().start(document.body)
There's an example called Ref - Examples that uses the ref
approach for contenteditable also, which I've noticed can be quirky in frameworks also for similar reasons.
I ran into another good usage for ref
. MaterializeCSS relies on input
elements having a specific type set, but when type="text"
will sometimes get stripped from the element because it's the default, causing the label animations not to work. I was able to use a ref
to specifically reset the type
attribute which fixed the issue.
This snippet (tested in playground) shows the issue:
When the textbox is EMPTY and you type one character, it immediately loses focus.