文本字段的自定义反应挂钩似乎已损坏

Custom react hook to for text field seems to be broken

我一直在尝试想出一个自定义挂钩来使文本字段可配置,即将数据集传递给一个自定义挂钩,它会给我需要使用的文本字段。

使用钩子的文本字段正在按预期呈现,但我不明白为什么这种方法会破坏使用自定义钩子创建的输入。每次击键后,输入都会失去焦点,并且不能像直接使用 useState 的其他输入一样工作。如果有人能解释哪里出了问题以及我未能理解的地方,那就太好了。

App.js

import React, { useState } from "react";
import ReactDOM from "react-dom";
import useTextFieldBroken from "./useTextFieldBroken";

import "./styles.css";

function App() {
  const [notBrokenValue, notBrokenSetValue] = useState("");

  const [TextFieldBrokenInputOne] = useTextFieldBroken(
    "brokenOne",
    "Broken Input One",
    ""
  );

  const notBrokenOnChange = e => {
    notBrokenSetValue(e.target.value);
  };

  return (
    <div>
      <label htmlFor="notBroken">
        <h3>Not Broken Input</h3>
        <input
          id="notBroken"
          onChange={notBrokenOnChange}
          value={notBrokenValue}
        />
      </label>
      <TextFieldBrokenInputOne />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

customHook.js

import React, { useState } from "react";

const useTextFieldBroken = (id, label, initialValue = "") => {
  const [value, setValue] = useState(initialValue);

  const handleChange = e => {
    setValue(e.target.value);
  };

  const TextField = () => {
    console.log("Rendered the input field");
    return (
      <label htmlFor={id}>
        <h3>{label}</h3>
        <input
          type="text"
          name={id}
          id={id}
          onChange={handleChange}
          value={value}
        />
      </label>
    );
  };

  return [TextField, value, setValue];
};

export default useTextFieldBroken;

https://codesandbox.io/s/4xj382vj40

您的输入正在失去焦点,因为您在每次更改时完全重新渲染创建它的树。

好消息是您不需要挂钩来执行此操作,只需将挂钩转换为功能组件即可:

App.js

import React, { useState } from "react";
import ReactDOM from "react-dom";
import TextFieldBroken from "./useTextFieldBroken";

import "./styles.css";

function App() {
  const [notBrokenValue, notBrokenSetValue] = useState("");

  const notBrokenOnChange = e => {
    notBrokenSetValue(e.target.value);
  };

  return (
    <div>
      <label htmlFor="notBroken">
        <h3>Not Broken Input</h3>
        <input
          id="notBroken"
          onChange={notBrokenOnChange}
          value={notBrokenValue}
        />
      </label>
      <TextFieldBroken label="Previously Broken" id="previously-broken" />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

customHook.js

import React, { useState } from "react";

const TextFieldBroken = ({ id, label, initialValue = "" }) => {
  const [value, setValue] = useState(initialValue);

  const handleChange = e => {
    setValue(e.target.value);
  };

  return (
    <label htmlFor={id}>
      <h3>{label}</h3>
      <input
        type="text"
        name={id}
        id={id}
        onChange={handleChange}
        value={value}
      />
    </label>
  );
};

export default TextFieldBroken;