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

标签 javascript reactjs react-hooks html-input

这个问题修改了 question在 r/reactjs 上。

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

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

这个问题在sandbox中得到了说明。 ,原始问题的作者用 10 毫秒的 setTimeout() 延迟修复了问题。

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

最佳答案

我认为的基本问题是 .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});
}

更改模板以调用handleSelection()

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

关于javascript - JavaScript 的 .setSelectionRange() 与 React Hooks 不兼容吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60129605/

相关文章:

javascript - 如何使用 React Hooks 更改多个条目?

javascript - 使用状态钩子(Hook)时,useState() 中的 react 如何为功能组件检索正确的状态对象和函数?

javascript - 仅显示 Google App Script 中的最后 12 行

javascript - 在过滤器 if 语句中拨号时遇到问题 - 多个下拉列表

javascript - 注入(inject)动态内容 react

reactjs - 通过 React useEffect Hook 更新状态时防止无限循环

没有引用的Javascript克隆变量

javascript - 为 highchart 面积图应用外边框

html - React 代码未在浏览器中显示

reactjs - React Checkbox 组件需要点击两次才能更改为选中状态