![](/img/trans.png)
[英]What's an efficient way to render child items of one of many list items in React?
[英]What is the correct way to select one of many child elements in React?
我有我的新 React 应用程序的一小部分,其中包含一个文本块AllLines
,拆分为名为Line
的逐行组件。 我想让它工作,以便当单击一行时,它将被选中并可编辑,而所有其他行将显示为<p>
元素。 我怎样才能最好地管理这里的状态,以便在任何给定时间只选择一行? 我正在努力解决的部分是确定以父元素可以更改其状态的方式单击了哪个Line
元素。
我知道如何完成这项工作,但我对 React 比较陌生,并试图通过正确地做事来让我的头脑进入“在 React 中思考”,所以我很想知道在这种情况下什么是最佳实践.
class AllLines extends Component {
state = {
selectedLine: 0,
lines: []
};
handleClick = (e) => {
console.log("click");
};
render() {
return (
<Container>
{
this.state.lines.map((subtitle, index) => {
if (index === this.state.selectedLine) {
return (
<div id={"text-line-" + index}>
<TranscriptionLine
lineContent={subtitle.text}
selected={true}
/>
</div>
)
}
return (
<div id={"text-line-" + index}>
<Line
lineContent={subtitle.text}
handleClick={this.handleClick}
/>
</div>
)
})
}
</Container>
);
}
}
class Line extends Component {
render() {
if (this.props.selected === true) {
return (
<input type="text" value={this.props.lineContent} />
)
}
return (
<p id={} onClick={this.props.handleClick}>{this.props.lineContent}</p>
);
}
}
在您的情况下,没有真正更简单的方法。 当前selected
Line
是“上方”行集合(父),这是正确的(对于兄弟姐妹需要知道的情况)。
但是,您可以简化代码很多:
<Container>
{this.state.lines.map((subtitle, index) => (
<div id={"text-line-" + index}>
<Line
handleClick={this.handleClick}
lineContent={subtitle.text}
selected={index === this.state.selectedLine}
/>
</div>
))}
</Container>
而对于Line
组件,最好使用函数式组件,因为它是无状态的,甚至不使用任何生命周期方法。
编辑:添加了缺少的右括号
“在 React 中思考”你会想要放弃通过它们的唯一id
来获取 DOM 元素的习惯;)
据我所知,您的代码库中缺少一些部分:
为了总结上述内容,我将您的代码稍微改写为以下内容:
const { Component } = React, { render } = ReactDOM const linesData = Array.from( {length:10}, (_,i) => `There goes the line number ${i}` ) class Line extends Component { render(){ return ( <p onClick={this.props.onSelect}>{this.props.lineContent}</p> ) } } class TranscriptionLine extends Component { constructor(props){ super(props) this.state = { content: this.props.lineContent } this.onEdit = this.onEdit.bind(this) } onEdit(value){ this.setState({content:value}) this.props.pushEditUp(value, this.props.lineIndex) } render(){ return ( <input style={{width:200}} value={this.state.content} onChange={({target:{value}}) => this.onEdit(value)} /> ) } } class AllLines extends Component { constructor (props) { super(props) this.state = { selectedLine: null, lines: this.props.lines } this.handleSelect = this.handleSelect.bind(this) this.handleEdit = this.handleEdit.bind(this) } handleSelect(idx){ this.setState({selectedLine:idx}) } handleEdit(newLineValue, lineIdx){ const linesShallowCopy = [...this.state.lines] linesShallowCopy.splice(lineIdx,1,newLineValue) this.setState({ lines: linesShallowCopy }) } render() { return ( <div> { this.state.lines.map((text, index) => { if(index === this.state.selectedLine) { return ( <TranscriptionLine lineContent={text} lineIndex={index} pushEditUp={this.handleEdit} /> ) } else return ( <Line lineContent={text} lineIndex={index} onSelect={() => this.handleSelect(index)} /> ) }) } </div> ) } } render ( <AllLines lines={linesData} />, document.getElementById('root') )
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.