【问题标题】:how to set focus to next input on enter key press in react js with refs如何在使用参考的反应js中将焦点设置为下一个输入
【发布时间】:2021-08-19 06:53:40
【问题描述】:

我在地图中使用多个输入,当我在 React Hooks 中单击输入时,我想将焦点设置为下一个输入。 在参考文献的帮助下

我正在使用材质 ui 文本字段来获取输入

我尝试在没有 ref 的 react 类组件中工作,但在钩子中它不起作用 类组件代码:

constructor(props) {
this.state = {}
}

inputRefs = [];

 _handleKeyPress = e => {
        const {currentTarget} = e;
            let inputindex = this.inputRefs.indexOf(currentTarget)
            if (inputindex < this.inputRefs.length - 1) {
                this.inputRefs[inputindex + 1].focus()
            }
            else {
                this.inputRefs[0].focus()
            }
      };

Inside render in 在地图函数中添加了这个

this.state.data.map((data) => return (
<TextField 
     inputProps = {{onKeyPress:(e) => this.function1(e, data)}}
     onChange={this.changevaluefunction} 
     inputRef={ref => this.inputRefs.push(ref)} 
     onFocus={this.handleFocus}  ref={`input${id}`} /> ))

【问题讨论】:

  • 你使用的是旧的 React ref 语法。使用createRef 创建一个 React 引用数组,并在尝试聚焦时访问当前值。能否提供更全面的组件代码示例? stackoverflow.com/help/minimal-reproducible-example
  • 是的,我当然可以更新问题

标签: javascript node.js reactjs react-hooks


【解决方案1】:

我使用功能组件以不同的方式实现了解决方案。我已经选择了 4 个字段,并使用 createRef 钩子设置了它的引用。

我可以从您的解决方案中看到,只要您在当前元素上按 Enter 键,您就希望将焦点移至下一个输入元素。

我将onKeyUp 处理程序中的下一个目标元素参数与实际事件一起传递,然后检测Enter 键是否被按下。如果按下Enter 键并且targetElem 存在,那么我将焦点移动到传递的targetElem。通过这种方式,您可以更好地控制输入。

你可以在这里查看我的解决方案

https://codesandbox.io/s/friendly-leftpad-2nx91?file=/src/App.js

import React, { useRef } from "react";
import TextField from "@material-ui/core/TextField";
import "./styles.css";

const inputs = [
  {
    id: "fName",
    label: "First Name"
  },
  {
    id: "lName",
    label: "Last Name"
  },
  {
    id: "gender",
    label: "Gender"
  },
  {
    id: "address",
    label: "Address"
  }
];

export default function App() {
  const myRefs = useRef([]);

  const handleKeyUp = (e, targetElem) => {
    if (e.key === "Enter" && targetElem) {
      targetElem.focus();
    }
  };

  return (
    <div>
      {inputs.map((ipt, i) => (
        <TextField
          onKeyUp={(e) =>
            handleKeyUp(e, myRefs.current[i === inputs.length - 1 ? 0 : i + 1])
          }
          inputRef={(el) => (myRefs.current[i] = el)}
          id={ipt.id}
          fullWidth
          style={{ marginBottom: 20 }}
          label={ipt.label}
          variant="outlined"
          key={ipt.id}
        />
      ))}
    </div>
  );
}

【讨论】:

  • @swaran nirla 感谢您的帮助,您正在使用动态 refs 如何在 map 函数中输入,然后我们如何在函数内传递数组 ojbect
  • @PraveenKumar 我已经根据您的需要更新了代码,a/c。请检查并投票赞成这个答案。
【解决方案2】:

您可以将 this.inputRefs 转换为 React ref,以便它在渲染中持续存在,除此之外,您几乎可以删除对任何 this 对象的所有引用。

示例组件:

const LENGTH = 10;
const clamp = (min, max, val) => Math.max(min, Math.min(val, max));

export default function App() {
  const [data] = useState([...Array(LENGTH).keys()]);

  const inputRefs = useRef([]); // <-- ref to hold input refs

  const handleKeyPress = index => () => {                   // <-- enclose in scope
    const nextIndex = clamp(0, data.length - 1, index + 1); // <-- get next index
    inputRefs.current[nextIndex].focus();                   // <-- get ref and focus
  };

  return (
    <div className="App">
      {data.map((data, index) => (
        <div key={index}>
          <TextField
            inputProps={{ onKeyPress: handleKeyPress(index) }}   // <-- pass index
            inputRef={(ref) => (inputRefs.current[index] = ref)} // <-- save input ref
          />
        </div>
      ))}
    </div>
  );
}

【讨论】:

  • 感谢您的帮助,先生,非常感谢您,您真棒,我有一个建议,而不是使用钳位,如果我们将一个添加到索引然后聚焦以及 inputRefs.current[nextIndex] && inputRefs .current[nextIndex].focus(); inputRefs.current[nextIndex].focus() 不起作用。只有当我们这样给予时它才有效。无论如何,谢谢先生。
  • @PraveenKumar 太棒了!我并不完全遵循所有这些建议,但听起来你只是想在索引中添加一个并对下一个 ref 是否真实进行空检查,如果它存在则关注它。如果此答案有助于解决您的问题/问题,那么我邀请您接受它,并且不要忘记在 SO 上为您认为有帮助和/或有用的答案和 cmets 投票。干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-16
  • 2017-02-10
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
相关资源
最近更新 更多