getElementById после условного рендеринга с помощью setState - PullRequest
0 голосов
/ 01 мая 2020

У меня есть триггерная кнопка, которая открывает диалоговое окно с вопросом, хочет ли пользователь включить текст в речь. Как только диалоговое окно открыто, я хочу сосредоточиться на кнопке «Да» в диалоговом окне, получив элемент кнопки по его идентификатору.

При нажатии триггера вызывается следующая функция:

  private openTTSDialog = () => {
    if (this.state.ttsDialog === true) {
      this.setState({ ttsDialog: false })
    } else {
      this.setState({ ttsDialog: true }, () => {
        // search document once setState is finished
        const yesButton = document.getElementById('tts-dialog-yes-button')
        log('yesButton', yesButton)
        if (yesButton) {
          yesButton.focus()
        }
      })
    }
  }

И мой диалог условно отображается с троичным выражением, подобным этому:

{
  this.state.ttsDialog ? (
    <div className="tts-dialog-container">
      <div className="tts-dialog-text-container">
        {session.ttsEnabled ? (
          <div>
            {
              strings.disableTTS
            }
          </div>
        ) : (
          <div>
            {
              strings.enableTTS
            }
          </div>
        )}
      </div>
      <div className="tts-dialog-button-container">
        <button
          aria-label={strings.yes}
          tabIndex={0}
          className="tts-dialog-button"
          id="tts-dialog-yes-button"     // this is the button I want to focus
          onClick={this.toggleTTS}
        >
          {
            strings.yes
          }
        </button>
        <button
          aria-label={strings.no}
          tabIndex={0}
          className="tts-dialog-cancelButton"
          onClick={this.closeTTSDialog}
        >
          {
            strings.no
          }
        </button>
      </div>
    </div>
  ) : null
}

Мой журнал для yesButton не определен. Я думал, что добавление функции обратного вызова к setState исправит это, потому что я буду искать документ после завершения setState, но я все еще что-то упускаю. Есть идеи, что это такое?

Ответы [ 2 ]

3 голосов
/ 01 мая 2020

В конструкторе вашего класса вы должны добавить ссылку на вашу кнопку:
this.myRef = React.createRef();
Затем в вашей кнопке:

<button
          ref={this.myRef}
          aria-label={strings.yes}
          tabIndex={0}
          className="tts-dialog-button"
          id="tts-dialog-yes-button"     // this is the button I want to focus
          onClick={this.toggleTTS}
        >

Наконец, вместо того, чтобы делать:

const yesButton = document.getElementById('tts-dialog-yes-button')

Вы должны сделать:

const yesButton = = this.myRef.current;
1 голос
/ 01 мая 2020

На самом деле я бы также подумал, что это должно сработать, поскольку вы используете обратный вызов на setState, поэтому новый рендер должен завершиться, а элемент уже должен быть подключен и доступен. В любом случае, я думаю, что идиоматический способ реагирования c будет состоять в том, чтобы использовать ref (https://reactjs.org/docs/refs-and-the-dom.html) и поместить его в кнопку, как <button ref={this.yesButton} ...>...</button>, а затем вызвать this.yesButton.focus(). Вы уже пробовали это?

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