Javascript 在React中选择多个子元素之一的正确方法是什么?
我的新React应用程序有一小部分,其中包含一块文本,Javascript 在React中选择多个子元素之一的正确方法是什么?,javascript,reactjs,Javascript,Reactjs,我的新React应用程序有一小部分,其中包含一块文本,AllLines,分为一行一行的组件,称为line。我想让它工作起来,这样当单击一行时,它将被选中并可编辑,而所有其他行将显示为元素。如何最好地管理此处的状态,以便在任何给定时间仅选择其中一行?我正在努力解决的部分是确定哪个行元素被单击,以便父元素可以更改其状态 我知道我可以用什么方法来做到这一点,但我对反应还比较陌生,我试图通过正确地做事来让自己的头脑进入“反应中思考”,因此我渴望找出在这种情况下的最佳做法 class AllLines e
AllLines
,分为一行一行的组件,称为line
。我想让它工作起来,这样当单击一行时,它将被选中并可编辑,而所有其他行将显示为
元素。如何最好地管理此处的状态,以便在任何给定时间仅选择其中一行?我正在努力解决的部分是确定哪个行
元素被单击,以便父元素可以更改其状态
我知道我可以用什么方法来做到这一点,但我对反应还比较陌生,我试图通过正确地做事来让自己的头脑进入“反应中思考”,因此我渴望找出在这种情况下的最佳做法
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>
);
}
}
类所有行扩展组件{
状态={
所选行:0,
行:[]
};
handleClick=(e)=>{
控制台日志(“单击”);
};
render(){
返回(
{
this.state.lines.map((副标题,索引)=>{
if(index==this.state.selectedLine){
返回(
)
}
返回(
)
})
}
);
}
}
类行扩展组件{
render(){
if(this.props.selected==true){
返回(
)
}
返回(
{this.props.lineContent}
);
}
}
在您的情况下,没有更简单的方法。当前选定的行的状态为“高于”行集合(父级),这是正确的(对于兄弟姐妹需要知道的情况)
但是,您可以大大简化代码:
{this.state.lines.map((副标题,索引)=>(
))}
对于Line
组件,最好使用功能组件,因为它是无状态的,甚至不使用任何生命周期方法
编辑:添加了缺少的右括号'Thinking in React',您可能希望放弃通过其唯一的id
;)获取DOM元素的习惯
据我所见,您的代码库中缺少几个部分:
- 一次只选择一行的智能单击处理程序
- 编辑将坚持回调的行处理程序,该回调将修改父状态中的行内容
- 对于能够编辑的行和实际编辑的行,最好有两个单独的组件,因为它们的行为方式不同,并且显示为不同的DOM元素
为了总结以上内容,我将稍微将您的代码改写为以下内容:
const{Component}=React,
{render}=ReactDOM
const linesData=Array.from(
{长度:10},
(u,i)=>`行号${i}出现了`
)
类行扩展组件{
render(){
返回(
{this.props.lineContent}
)
}
}
类转录行扩展组件{
建造师(道具){
超级(道具)
此.state={
内容:this.props.lineContent
}
this.onEdit=this.onEdit.bind(this)
}
onEdit(值){
this.setState({content:value})
this.props.pushEditUp(值,this.props.lineIndex)
}
render(){
返回(
this.onEdit(值)}
/>
)
}
}
类AllLines扩展组件{
建造师(道具){
超级(道具)
此.state={
selectedLine:null,
台词:这个。道具。台词
}
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]
LinesHallowCopy.splice(lineIdx,1,newLineValue)
这是我的国家({
行:行HallowCopy
})
}
render(){
返回(
{
this.state.lines.map((文本,索引)=>{
if(index==this.state.selectedLine){
返回(
)
}
其他的
返回(
this.handleSelect(index)}
/>
)
})
}
)
}
}
渲染(
,
document.getElementById('root'))
)
谢谢!我想我唯一的另一个问题是关于如何检索被单击元素的id。在div id上的那一刻,是否有任何方式(或原因)可以在子元素上实现这一点?谢谢你对简化的建议。我本来打算这么做,但现在还没来得及去做。你的handleClick
可以返回一个当前id
作为闭包的函数:handleClick=(id)=>(event)=>this.setState({…selectedLine:id}尽管你已经得到了已接受的答案,但从你下面的评论看来,你的问题还没有完全解决。如果你的问题仍然存在,你不会介意考虑其他选项,你可能想退房,然后对输入的YvGEN进行实况演示,我已经把它变成了接受的答案SUNC。这更接近我想要的。我已经找到了解决方案
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>
);
}
}
<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>