我已经使用Bootstrap为Accordion中的卡创建了Row和Col组件-简单,而不是React.Bootstrap或其他什么。Row和Col只是向他们的孩子们展示,Card只是有更多的道具,也只是向孩子们展示。比如:
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} />
<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} />
</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((版本将焦点保持在文本区域,但当我键入时,第二个版本在键入第一个字母后将焦点从文本区域移开并清除文本区域。也就是说,我不可能输入一些长文本——我只收到一封信。
我错过了什么?为什么会发生这种情况,以及如何使焦点稳定?
正如注释中已经提示的那样,Col
和Row
组件上的每个渲染都有唯一的键,因为key={shortid.generate()}
。
在textarea
中写入一个字符后,您很可能会更改状态,然后重新发布,在当前textarea
的位置,会出现一个新的字符,自然没有焦点。
我建议您仔细阅读为什么在React中创建keys
。链接https://reactjs.org/docs/lists-and-keys.html#keys.
我必须马上说,创建它们是为了识别列表项,当您在每个渲染上生成唯一的keys
时,这是完全违反的。