对于文本字段的自定义反应挂钩似乎被破坏了

问题描述 投票:0回答:1

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

使用钩子的文本字段正在按预期呈现,但我不明白为什么这种方法破坏了使用自定义钩子创建的输入。每次击键后,输入都会失去焦点,而不是直接使用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

reactjs react-hooks
1个回答
1
投票

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

好消息是你不需要钩子就可以做到这一点,只需将钩子转换为功能组件:

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;
© www.soinside.com 2019 - 2024. All rights reserved.