Предотвращение нескольких вызовов автофокуса в компоненте material-ui <TextField> - PullRequest
0 голосов
/ 11 сентября 2018

Этот вопрос относится к компоненту material-ui <TextField>, однако решение, скорее всего, можно найти в самой React.

Представьте, что мы делаем простую форму авторизации. Форма входа представлена ​​конечным автоматом.

{
  empty: {},
  filled: { typing, authenticating }
}

У меня есть компонент <LoginForm>, который отображает два компонента <TextField> и <Button>. Первый <TextField> автофокусируется при монтировании. Довольно просто.

У меня есть родительский компонент, который управляет текущим состоянием компьютера и отображает различные компоненты в зависимости от его значения следующим образом:

  • empty: <Empty> компонент, который отображает <LoginForm> с определенными реквизитами
  • заполнено: <Wrapper> компонент - эквивалент <Fragment>

Любое из состояний под filled отображается как потомок <Wrapper>.

  • набрав: <Typing> компонент, который рендерит <LoginForm> с разными реквизитами
  • аутентификация: <Authenticating> компонент, который отображает счетчик.
Состояние

empty переходит в filled, когда один компонентов <TextBox> больше не пуст.


Проблема:

Представьте, что мы начинаем в состоянии empty. Он визуализирует <Empty>, что делает <LoginForm>, что делает имя пользователя <TextField> с автофокусом.

Мы сосредоточились на вводе имени пользователя и начали печатать. Все хорошо.

Однако представьте, что мы сначала начали вводить пароль (то есть 2-й <TextBox>, который не выполняет автофокусировку). Мы начинаем с состояния empty, пишем первую букву нашего пароля, переходим в состояние filled>typing, которое, кажется, перемонтирует <LoginForm>, и снова автоматически фокусируемся на ввод имени пользователя. В результате вы можете написать первую букву для пароля, а последующие буквы будут добавлены к имени пользователя из-за повторной автофокусировки.

Я полагал, что разметка, создаваемая response, по существу такая же (благодаря компонентам-оберткам без их рендеринга), что перемонтирования не будет, и, таким образом, мы получим автофокус только при первом монтировании (т.е. когда начиная с empty).

Как я могу решить эту проблему?

1 Ответ

0 голосов
/ 12 сентября 2018

До (проблемный код):

const LoginMachineDelegator = () => {
  const props = {
    machine: init.machine,
    render: {
      [init.STATES.EMPTY]: Empty,
      [init.STATES.FILLED]: Wrapper,
      [init.STATES.TYPING]: Typing,
      [init.STATES.AUTHENTICATING]: Authenticating
    }
  }

  return <MachineDelegator {...props}/>;
}

Реагировать на дерево компонентов в empty состояние:

MachineDelegator > Empty > LoginForm

Реагировать на дерево компонентов в filled>typing состояние:

MachineDelegator > Wrapper > Typing > LoginForm


После (согласованный код):

const LoginMachineDelegator = () => {
  const props = {
    machine: init.machine,
    [init.STATES.EMPTY]: { func: createEmptyLoginForm },
    [init.STATES.FILLED]: { /* no element */ },
    [init.STATES.TYPING]: { func: createTypingLoginForm },
    [init.STATES.AUTHENTICATING]: { component: Authentication }
  }
}

Поскольку функции возвращают реагирующий элемент, они сами не вставляютсяв дерево компонентов React.Вместо этого возвращаемый элемент есть.Таким образом, новое дерево компонентов будет выглядеть так:

в состоянии empty:

MachineDelegator > LoginForm

в состоянии filled>typing:

MachineDelegator > LoginForm


Это гарантирует, что LoginForm не будет перемонтирован и перерисован

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