React textarea 意外失去焦点

React textarea loses focus unexpectedly

我已经使用 Bootstrap 在 Accordion 中为 Card 创建了一个 Row 和一个 Col 组件 - 简单,而不是 React.Bootstrap 或其他。 Row 和 Col 只是显示他们的 children,Card 只是有更多的道具,也只是显示 children。像那样:

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 中显示这些更改。我还有一个按钮,可以根据 clipboard.js

将文本复制到缓冲区

渲染功能的第一个版本工作得很好,但它没有给我所需的设计,所以我想出了第二个版本,基于 Row 和 Col 组件,如上所述。

内容主要没有区别——同样的textarea、checkbox、button和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() 版本将焦点保持在文本区域中,但当我键入时,第二个版本在键入第一个字母后将焦点从文本区域中移开并清除文本区域。那就是我无法输入一些长文本 - 我只收到一个字母。

我错过了什么?为什么会出现这种情况以及如何使焦点稳定?

正如评论中提示的那样,ColRow 组件上的每个渲染都有唯一的键,因为 key={shortid.generate()}.

textarea 中写入一个字符后,您很可能会更改状态,然后重新渲染并在当前 textarea 的位置出现一个新的,自然没有焦点。

我建议你仔细阅读为什么在 React 中创建 keys。 Link https://reactjs.org/docs/lists-and-keys.html#keys.

我必须马上说,创建它们是为了识别列表项,当您在每个渲染器上生成唯一的 keys 时,这是完全违反的。

请将 'value' 属性 添加到您的文本区域