将 useRef 与 Array 反应为动态

zyn*_*nkn 3 reactjs react-hooks

我试图使每个字母输入时焦点移动到下一个输入的组件。

我想我需要多个ref像数组一样,但我不知道。

这是问题的示例代码。

function PIN({length, onChange, value}){
  const inputEl = React.useRef(null);
  function handleChange(e){
    onChange(e);
    inputEl.current.focus(); 
  }
  return (
    <div>
      {
        new Array(length).fill(0).map((i)=>(
          <input type="text" ref={inputEl} onChange={handleChange} />
        ))
      }
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

wan*_*ang 10

输入上的 ref 等效于回调函数。你可以传一个方法给他。该方法接收的参数是输入的dom元素,可以存储在数组中。

import React from "react";
import "./styles.css";

export default function App() {
  const inputEl = React.useRef([]);
  function handleChange(i){
    inputEl.current[i+1].focus(); 
  }
  return (
    <div>
      {
        new Array(3).fill(0).map((n,i)=>(
          <input 
          key={i} 
          type="text" 
          ref={ref=>inputEl.current.push(ref)} 
          onChange={()=>handleChange(i)} 
          />
        ))
      }
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

  • 这不会导致数组不断扩大吗?假设您有 3 个输入元素。第一次渲染后,数组长度将为 3。但重新渲染后,这 3 个项目将再次被推送。所以是的,前 3 个数组元素完好无损,但数组长度现在是 6(然后是 9、12 等等......) (5认同)
  • @AhashanAlamSojib 当然,但是如果你可以避免问题,为什么要解决它呢?这就是我所做的: `ref={ref =&gt; { if (ref) elements.current[key] = ref }}` (elements 不是一个数组,而是一个简单的 JS 对象,并且 key 与在地图功能) (5认同)

Zoh*_*jaz 10

您可以创建多个引用

function PIN({length, onChange, value}){
  const inputRefs = useMemo(() => Array(length).fill(0).map(i=> React.createRef()), []);
  const handleChange = index => (e) => {
    //onChange(e); // don't know about the logic of this onChange if you have multiple inputs
    if (inputRefs[index + 1]) inputRefs[index + 1].current.focus(); 
  }
  return (
    <div>
      {
        new Array(length).fill(0).map((inp, index)=>(
          <input type="text" ref={inputRefs[index]} onChange={handleChange(index)} />
        ))
      }
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您正在打字稿中寻找答案: `const inputRefs: React.RefObject&lt;HTMLInputElement&gt;[] = useMemo( ...` (2认同)