使用Hooks创建组件进行反应

时间:2020-04-26 08:47:13

标签: reactjs react-hooks

我正在尝试使用一个钩子来创建一个文本框,该文本框将值状态作为钩子的一部分提供。

但是,我并不是很成功,因为每当我尝试键入时,文本框都会失去焦点。

如果我展示自己在做什么,这可能更有意义。

请参阅此Codepen进行快速演示。 (https://codepen.io/david_yau/pen/RwWVoKz?editors=1111

详细说明

// My first attempt
// App.jsx, the App
const App = () => {
  const [text, TextBox] = useTextBox();

  return (
    <div>
      <TextBox />
      <p>
        text: {text}
      </p>
    </div>
  )
}

// useTextBox.jsx
const useTextBox = () => {
  const [text, setText] = React.useState("");

  const onChange = (event) => {
    setText(event.target.value);
  }

  const TextBox = () => {
    return (
      <input type="text" value={text} onChange={onChange} />
    )
  };

  return [text, TextBox];
}

这种方式行不通,因为每次我在文本框中键入内容时,焦点都会丢失。

但是,如果我将实现更改为以下内容,它将起作用。

此实现之间的区别在于,上述实现是使用<TextBox />渲染一个新的TextBox。最底层的是使用渲染的文本框,例如{TextBox}

// App.jsx
const App = () => {
  const [text, TextBox] = useTextBoxOne();

  return (
    <div>
      <h1> This one work </h1>
      {TextBox}
      <p>
        text: {text}
      </p>
    </div>
  )
}

// useTextBox.jsx
const useTextBox = () => {
  const [text, setText] = React.useState("");

  const onChange = (event) => {
    setText(event.target.value);
  }

  const TextBox = (
      <input type="text" value={text} onChange={onChange} />
    );

  return [text, TextBox];
}

如果有帮助的话,我从“ {H3}}课程的“ Custom Hook”课程中得到了这个想法。

由于这是一个很长的帖子,所以只需重申一下这个问题。我想知道为什么第一种方法不起作用,因为它不断失去关注,而第二种方法却失去了作用。

1 个答案:

答案 0 :(得分:2)

因为const TextBox = () => <input />将在每次调用useTextBoxTwo()时创建一个不同的React组件,而const TextBox = <input />只是一个React元素,呈现在同一Component中(在App中)

在当前实现中,当组件内部的元素发生更改时,ReactDOM会检查它是否具有相同的元素名称(例如“ input”)并且没有不同的key-为true时,它将重新使用相同的DOM元素,例如以下2个React元素将重用相同的DOM元素(不会失去焦点):

{condition ? <input value="a" /> : <input value="b" />}

但是2种不同的React组件将触发旧组件的卸载,将其从DOM中删除,然后安装新组件,从而创建新的DOM元素(=>失去焦点)。


因此,请勿在自定义钩子内创建组件,而应创建使用钩子的自定义组件。