JavaScript 的 .setSelectionRange() 与 React Hooks 不兼容吗?



这个问题改进了关于r/reactjs的问题。

我有一个受控input,我可以通过编程方式更改其值。我想使用.setSelectionRange()来保持输入中的插入符号位置。

除了这不起作用:默认情况下,每次重新渲染都会自动将选择范围设置为输入的末尾

这个问题在这个沙盒中得到了说明,原始问题的作者用 10 毫秒的setTimeout()延迟解决了问题。

如何在不使用与 Hooks 不兼容的setTimeout()getSnapshotBeforeUpdate()的情况下实现这一点?

在我看来,基本问题是.setSelectionRange()在模板中内联使用,应该包装在useEffect()中。

我也会拉出选择处理程序,只是为了更整洁一点(根据handleDomainChange()handleSubmit()(。

使用选择更新的效果

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});
}

模板更改为调用句柄选择((

<Picker
set="emojione"
onSelect={event => {
handleSelection(event)
}}
/>

原始代码供参考

<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
);
}}
/>

相关内容

  • 没有找到相关文章

最新更新