【问题标题】:React dynamic form input ref typeError反应动态表单输入参考类型错误
【发布时间】:2022-01-11 18:24:50
【问题描述】:

我有一个带有动态输入字段的 React 表单,用户可以添加和删除输入字段。我在提交表单时进行验证。如果 input 为空,则 input 使用 useRef 钩子聚焦。问题是,如果我有两个输入为空,所以我添加第二个输入并在之后将其删除,我得到 typeError“无法读取 null 的属性(读取'焦点')”。我也尝试过使用动态 useRef 输入,但我无法修复它。

CodeSandBox

App.js

import React, { useState, useRef } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  const [fields, setFields] = useState([""]);

  const fieldRef = useRef();

  const fieldsIsValid =
    fields.length >= 1 && fields.every((field) => field.trim() !== "");

  function handleChange(i, event) {
    const values = [...fields];
    values[i] = event.target.value;
    setFields(values);
  }

  function handleAdd() {
    const values = [...fields];
    values.push("");
    setFields(values);
  }

  function handleRemove(i) {
    const values = [...fields];
    values.splice(i, 1);
    setFields(values);
  }

  function submitHandler(event) {
    event.preventDefault();

    if (!fieldsIsValid) {
      if (fields.length >= 1) {
        fieldRef.current.focus();
        return;
      }
      return;
    }
    console.log(fields);
  }

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <form onSubmit={submitHandler}>
        <button type="button" onClick={() => handleAdd()}>
          Add Input
        </button>
        {!fieldsIsValid && <p className="error">Input is required</p>}
        {fields.map((field, idx) => {
          return (
            <div key={`${"input"}-${idx}`}>
              <input
                type="text"
                placeholder="Enter text"
                value={field || ""}
                ref={fieldRef}
                onChange={(e) => handleChange(idx, e)}
              />
              <button type="button" onClick={() => handleRemove(idx)}>
                X
              </button>
            </div>
          );
        })}
        <button className="margin-top" type="submit">
          Submit
        </button>
      </form>
    </div>
  );
}

export default App;

【问题讨论】:

    标签: javascript reactjs react-hooks use-ref dynamic-forms


    【解决方案1】:

    您需要使用inputRef 来始终跟踪您想要关注哪一个。例如删除后,将 inputRef 指向最后一个非空输入。

    这样做的另一种想法(我认为更好)是通过常规 js 代码。这样你就不用担心一直跟踪最后一个,你只需关注第一个空的输入。

    const inputRefs = document.querySelectorAll("#myform input");
    for (let i = 0; i < inputRefs.length; i++) {
      if (!inputRefs[i].value && inputRefs[i].required) {
        inputRefs[i].focus();
        break;
      }
    }
    

    https://codesandbox.io/s/react-dynamic-form-forked-8gnww

    编辑:更新以生成一些必需的输入

    【讨论】:

    • 实际上我有一个带有静态文本输入、电子邮件输入、电话输入、映射选择和一些动态输入字段等的大表单。每个都有不同的验证。我只发布我表格的一部分。例如,一些静态文本输入不是必需的,因此它们不需要获得焦点。所以我认为这不会奏效。我想我需要动态引用,但我无法修复它。
    • 您可以随时添加其他字段,例如requireddata-required,甚至只是一个类名或其他您需要获得焦点的输入,我认为您不需要动态参考。 inputRefs[i] 是表单中的所有引用。您可以更新查询以满足您的需求
    • 它适用于您的答案,所以我接受作为答案。但是,我把 ref 放在表单标签上。
    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多