Реакция textarea неожиданно теряет фокус - PullRequest
1 голос
/ 22 февраля 2020

Я создал компоненты Row и Col для Карты в Accordion, используя Bootstrap - просто, не React. Bootstrap или что-то еще. Роу и Кол просто показывают своих детей, на Карте больше реквизита, а также просто показывает детям. Например:

class Col extends React.Component {render () {return (
      <div  className='col' id={'col_'+this.props.colid} key={shortid.generate()}>
        {this.props.children}
      </div>)}}

class Row extends React.Component {render () { return (
        <div  className='row' id={'row_'+this.props.rowid} key={shortid.generate()}>
          {this.props.children}
        </div>)}}

Затем я хочу вставить текстовую область, которая снабжена функцией для внесения некоторых изменений в текст, и я отображаю эти изменения в элементе div ниже текстовой области. Также у меня есть кнопка, которая копирует текст в буфер на основе буфера обмена. js

Первая версия функции рендеринга работает просто отлично, но она не дает мне необходимый дизайн, поэтому Я придумал вторую версию, основанную на компонентах Row и Col, описанных выше.

Содержимое в основном не отличается - это те же текстовые области, флажки, кнопки и div. Что отличается это макет. В первой версии макета вообще нет, во второй я старался изо всех сил :)

Итак:

  render () { return (<React.Fragment>
        <textarea id='xng0' onChange={this.handleChange} ref={this.xng0ref} />&nbsp;
        <CopyButton target="st0" message="Copy text" /> <br />
        <input type='checkbox' onChange={this.toggleTranslit} 
               defaultChecked={this.state.tranParam} /><span>Translit?</span><br />
        <div id='st0' border='1' ref={this.st0ref} >
          {this.state.st0value}
        </div></React.Fragment>)}

Вторая версия:

  render () {return ( <React.Fragment><Row><Col>
            <textarea id='xng0' onChange={this.handleChange} ref={this.xng0ref} />&nbsp;
              </Col><Col><Row><Col>
                <CopyButton target="st0" message="Copy text" />
              </Col></Row>
            <Row><Col>
                <input  type='checkbox' onChange={this.toggleTranslit} 
                        defaultChecked={this.state.tranParam}
                    /><span>Translit?</span>
              </Col></Row>
          </Col>
        </Row>
        <Row>
          <div id='st0' border='1' ref={this.st0ref}>
            {this.state.st0value}
          </div></Row></React.Fragment>)}

Моя проблема: в то время как первая версия render () сохраняет фокус в текстовой области, когда я набираю текст, вторая версия сбрасывает фокус с текстовой области после ввода первой буквы И очищает текстовую область. То есть у меня нет возможности ввести какой-то длинный текст - я получаю только одно письмо.

Что я пропустил? Почему это происходит и как сделать фокус стабильным?

Ответы [ 2 ]

1 голос
/ 22 февраля 2020

Как вам уже было предложено в комментариях, у вас есть уникальные ключи для каждого рендера на Col и Row компонентах, потому что key={shortid.generate()}.

После написания символа в textarea вы, скорее всего, измените состояние, затем произойдет повторное отображение, и вместо текущего textarea появится новое, естественно, без фокуса.

Я рекомендую внимательно прочитать, почему создаются keys в реакции. Ссылка https://reactjs.org/docs/lists-and-keys.html#keys.

Сразу скажу, что они были созданы для идентификации элементов списка, что полностью нарушается при генерации уникального keys на каждом рендере.

0 голосов
/ 22 февраля 2020

пожалуйста, добавьте свойство 'value' к вашей текстовой области

...