6 javascript html-input reactjs react-hooks
这个问题改进了 r/reactjs 上的一个问题。
我有一个控件input,我可以通过编程方式更改其值。我想使用它.setSelectionRange()来保持输入中的插入符位置。
但这不起作用:默认情况下,每次重新渲染都会自动将选择范围设置为输入的末尾。
此沙箱中说明了该问题,原始问题的作者以 10 毫秒的setTimeout()延迟修复了该问题。
如何在不使用与 Hooks 不兼容的setTimeout()or 的情况下实现此目的?getSnapshotBeforeUpdate()
我看到的基本问题是.setSelectionRange()在模板中内联使用,并且应该包装在useEffect().
我还将拉出选择处理程序,只是为了更整洁(根据handleDomainChange()和handleSubmit())。
useEffect 用于选择更新
const[selection, setSelection] = useState()
useEffect(() => {
if (!selection) return; // prevent running on start
const {start, end} = selection;
inputEl.current.focus();
inputEl.current.setSelectionRange(start, end);
}, [selection])
const handleSelection = (e) => {
const start = inputEl.current.selectionStart;
const end = inputEl.current.selectionEnd;
... // other code within selection handler as per original
// inputEl.current.focus();
// // the line below doesn't work!
// // inputEl.current.setSelectionRange(start + e.native.length, end + e.native.length)
// //this one does, but is not good practice..
// setTimeout(
// () =>
// inputEl.current.setSelectionRange(
// start + e.native.length,
// end + e.native.length
// ),
// 10
// );
setSelection({start: start + e.native.length, end: end + e.native.length});
}
Run Code Online (Sandbox Code Playgroud)
模板更改为调用handleSelection()
<Picker
set="emojione"
onSelect={event => {
handleSelection(event)
}}
/>
Run Code Online (Sandbox Code Playgroud)
原始代码供参考
<Picker
set="emojione"
onSelect={e => {
const start = inputEl.current.selectionStart;
const end = inputEl.current.selectionEnd;
//const result = domainString.substring(0, start) + e.native + domainString.substring(end, domainString.length)
setDomainString(
prevString =>
prevString.substring(0, start) +
e.native +
prevString.substring(end, prevString.length)
);
setDomainsArray(
domainEndings.map(
ending =>
domainString.substring(0, start) +
e.native +
domainString.substring(end, domainString.length) +
ending
)
);
inputEl.current.focus();
// the line below doesn't work!
// inputEl.current.setSelectionRange(start + e.native.length, end + e.native.length)
//this one does, but is not good practice..
setTimeout(
() =>
inputEl.current.setSelectionRange(
start + e.native.length,
end + e.native.length
),
10
);
}}
/>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8030 次 |
| 最近记录: |