Реагируйте, используя крючки для создания компонента - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь использовать ловушку для создания текстового поля, которое предоставляет состояние значения как часть ловушки.

Однако я не совсем успешен, так как текстовое поле теряет фокус всякий раз, когда я пытаюсь печатать.

Это, вероятно, имеет больше смысла, если я покажу, что я делаю.

Пожалуйста, посмотрите этот 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];
}

Если это вообще поможет, я получил эту идею из этого курса: https://frontendmasters.com/courses/complete-react-v5/, вокруг Сессия "Custom Hook".

Просто чтобы повторить вопрос, так как это довольно длинный пост. Мне интересно, почему первый подход не работает, потому что он теряет фокус, в то время как второй работает.

1 Ответ

2 голосов
/ 26 апреля 2020

Поскольку const TextBox = () => <input /> будет создавать новый компонент React при каждом вызове useTextBoxTwo(), тогда как const TextBox = <input /> - это просто элемент React, отображаемый в том же компоненте (в App).

В в текущей реализации, когда элемент внутри компонента изменяется, ReactDOM проверяет, имеет ли он одинаковое имя элемента (например, «input») и не имеет другого key - при true он повторно использует один и тот же элемент DOM, Например, следующие 2 элемента React будут повторно использовать один и тот же DOM-элемент (без потери фокуса):

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

Но 2 различных компонента React вызовут размонтирование старого, удаление его из DOM и установку новый, создание нового элемента DOM (=> потеря фокуса).


Итак, не создавайте компоненты внутри пользовательских хуков, создавайте пользовательские компоненты, которые используют хуки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...