React Hooks - ввод теряет фокус, когда набирается 1 символ - PullRequest
1 голос
/ 13 января 2020

Я играю с React Hooks - переписываю форму для использования понятий ловушек. Все работает, как и ожидалось, за исключением того, что после ввода любого 1 символа на входе, ввод теряет фокус.

Полагаю, существует проблема, заключающаяся в том, что внешняя сторона компонента не знает о внутренних изменениях компонента. , но как мне решить эту проблему?

Вот хук useForm:

import React, { useState } from "react";

export default function useForm(defaultState, label) {
  const [state, setState] = useState(defaultState);

  const FormComponent = () => (
    <form>
      <label htmlFor={label}>
        {label}
        <input
          type="text"
          id={label}
          value={state}
          placeholder={label}
          onChange={e => setState(e.target.value)}
        />
      </label>
    </form>
  );

  return [state, FormComponent, setState];
}

Вот компонент, который использует хук:

function App() {
  const [formValue, Form, setFormValue] = useForm("San Francisco, CA", "Location");

  return (
    <Fragment>
      <h1>{formValue}</h1>
      <Form />
    </Fragment>
  );
}

Ответы [ 2 ]

2 голосов
/ 13 января 2020

При вводе любого текста в поле ввода. Родительский компонент также выполняет повторную визуализацию. Поэтому вам нужно сосредоточиться на вводе вручную. Для этого используйте autoFocus во входном теге

<input
  type="text"
  id={label}
  value={state}
  placeholder={label}
  onChange={e => setState(e.target.value)}
  autoFocus
/>
1 голос
/ 03 марта 2020

Хотя ответ Кайса разрешит симптомы, он не будет устранять причину. Он также потерпит неудачу, если будет несколько входов - какой из них должен автоматически фокусироваться при повторном рендеринге?

Проблема возникает, когда вы определяете компонент (FormComponent) внутри области действия другой функции, которая вызывается при каждом рендеринге вашего компонента App. Это дает вам совершенно новый FormComponent каждый раз, когда ваш App компонент перерисовывается и вызывает useState. Этот новый компонент тогда, ну, без внимания.

Лично я чувствовал бы, что возвращаю компоненты с крючка. Вместо этого я бы определил компонент FormComponent и возвращал бы состояние только из состояния useForm.

Но рабочий пример, ближайший к вашему исходному коду, может быть:

// useForm.js
import React, { useState } from "react";

// Define the FormComponent outside of your useForm hook
const FormComponent = ({ setState, state, label }) => (
  <form>
    <label htmlFor={label}>
      {label}
      <input
        type="text"
        id={label}
        value={state}
        placeholder={label}
        onChange={e => setState(e.target.value)}
      />
    </label>
  </form>
);

export default function useForm(defaultState, label) {
  const [state, setState] = useState(defaultState);

  return [
    state,
    <FormComponent state={state} setState={setState} label={label} />,
    setState
  ];
}
// App.js
import useForm from "./useForm";

export default function App() {
  const [formValue, Form] = useForm("San Francisco, CA", "Location");

  return (
    <>
      <h1>{formValue}</h1>
      {Form}
    </>
  );
}

Вот песочница

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