Asp.net mvc 为什么反应列表切片总是删除最后一行
我在Angular中有类似的代码,它工作得很好。我试图将代码转换为React版本。它工作得很好,除非我尝试删除一行。每次单击“删除”都会删除最后一行。我的期望是在单击“删除”按钮时删除该行。我正在传递需要删除的索引项。我提供了下面的样本,你也可以在这里尝试Asp.net mvc 为什么反应列表切片总是删除最后一行,asp.net-mvc,reactjs,Asp.net Mvc,Reactjs,我在Angular中有类似的代码,它工作得很好。我试图将代码转换为React版本。它工作得很好,除非我尝试删除一行。每次单击“删除”都会删除最后一行。我的期望是在单击“删除”按钮时删除该行。我正在传递需要删除的索引项。我提供了下面的样本,你也可以在这里尝试 类MineCts扩展React.Component{ 建造师(道具){ 超级(道具); 此.state={ 项目:[] }; } render(){ 返回( this.add(event)}>add 这是一个示例: {this.state.i
类MineCts扩展React.Component{
建造师(道具){
超级(道具);
此.state={
项目:[]
};
}
render(){
返回(
this.add(event)}>add
这是一个示例:
{this.state.items.map((记录,索引)=>{
返回(
remove(事件、记录、索引)}>remove
)
})}
)
}
onDataChange(e)
{
console.log(e.target.id)
this.setState({[e.target.id]:e.target.value})
}
加(e){
让行=this.state.items;
rows.push({});
this.setState({items:rows})
}
删除(e、记录、索引){
console.log(记录)
console.log(索引)
让行=this.state.items;
行。拼接(索引,1);
this.setState({items:rows})
}
}
ReactDOM.render(,mountNode)
仔细检查后,问题是由于:
<tr key={record.index}>
这实际上并没有被设置,您的孩子没有唯一的密钥,所以React不知道这些孩子中的哪一个被修改了,所以当您删除其中一个孩子时,会有点困惑
您需要为每个记录提供唯一的密钥
我更新了您的代码,并使用newdate().getTime()
作为获取唯一密钥的快速方法
我在这里有一个工作示例
添加记录时,您将看到每个记录的唯一键的值被显示,并且您将注意到只有特定的行被删除
删除一行后,输入字段为空的原因是您需要保存记录的输入值。仔细检查后,问题是由于:
<tr key={record.index}>
这实际上并没有被设置,您的孩子没有唯一的密钥,所以React不知道这些孩子中的哪一个被修改了,所以当您删除其中一个孩子时,会有点困惑
您需要为每个记录提供唯一的密钥
我更新了您的代码,并使用newdate().getTime()
作为获取唯一密钥的快速方法
我在这里有一个工作示例
添加记录时,您将看到每个记录的唯一键的值被显示,并且您将注意到只有特定的行被删除
删除一行后,输入字段为空的原因是您需要保存记录的输入值。您可以直接在删除函数上设置状态 我是说
remove(index) {
this.setState({
items: this.state.items.filter((s, sindex) => index !== sindex),
});
}
您可以直接在remove函数上设置state 我是说
remove(index) {
this.setState({
items: this.state.items.filter((s, sindex) => index !== sindex),
});
}
谢谢大家的反馈。这很有帮助。我了解到,如果您使用React行,则需要具有唯一的键。使用过滤器而不是“拼接”也很有帮助。我必须添加更改事件。当我把一个组件组合成多个组件时,我发现它非常有用。我更新了解决方案,以便在删除一行后不会删除输入字段。我还意识到,与AngularReact不同,React只进行单向绑定,每次数据更改都必须通过状态更新。以下是完整的解决方案:。特别感谢用户2340824的持续反馈。 以下是最终代码:
class MineCts extends React.Component{
constructor(props){
super(props);
this.state = {
items:[]
};
this.add = this.add.bind(this);
this.onDataChange = this.onDataChange.bind(this);
this.remove = this.remove.bind(this);
}
render(){
return(
<div>
<div><button onClick={this.add} >Add</button></div>
<div>
This is sample:
{this.state.items.map((record, index)=>{
return(
<DetailTable record ={record} callOnChangeFunc={this.onDataChange} callOnRemoveFunc={this.remove} />
);
})}
</div>
</div>
)
}
onDataChange(e, record)
{
e.preventDefault();
let rows = [...this.state.items];
record[e.target.id]=e.target.value;
rows[record.Id] = record;
this.setState({items:rows})
}
add(e){
let rows = [...this.state.items];
rows.push({Id: new Date().getTime(), Name:null, Counter:null});
this.setState({items:rows})
}
remove(e, record){
e.preventDefault();
let rows = [...this.state.items.filter(x=>x.Id!==record.Id)];
this.setState({items:rows})
}
}
class DetailTable extends React.Component{
constructor(props){
super();
this.callOnChange = this.callOnChange.bind(this);
this.callOnRemove = this.callOnRemove.bind(this);
}
callOnChange(e){
this.props.callOnChangeFunc(e, this.props.record);
}
callOnRemove(e){
this.props.callOnRemoveFunc(e, this.props.record);
}
render(){
return (
<div>
<table>
<tr key={this.props.record.Id} >
{this.props.record.Id}
<td>
<input id="Name" value={this.props.record.Name} onChange={this.callOnChange} /> </td>
<td>
<input id="Counter" value={this.props.record.Counter} onChange={this.callOnChange} /> </td>
<td><button onClick={this.callOnRemove} >Remove</button></td>
</tr>
</table>
</div>
);
}
}
ReactDOM.render(<MineCts />, document.querySelector("#app"))
类MineCts扩展React.Component{
建造师(道具){
超级(道具);
此.state={
项目:[]
};
this.add=this.add.bind(this);
this.onDataChange=this.onDataChange.bind(this);
this.remove=this.remove.bind(this);
}
render(){
返回(
添加
这是一个示例:
{this.state.items.map((记录,索引)=>{
返回(
);
})}
)
}
onDataChange(e,记录)
{
e、 预防默认值();
让行=[…this.state.items];
记录[e.target.id]=e.target.value;
行[record.Id]=记录;
this.setState({items:rows})
}
加(e){
让行=[…this.state.items];
rows.push({Id:new Date().getTime(),Name:null,Counter:null});
this.setState({items:rows})
}
删除(e,记录){
e、 预防默认值();
让行=[…this.state.items.filter(x=>x.Id!==record.Id)];
this.setState({items:rows})
}
}
类DetailTable扩展了React.Component{
建造师(道具){
超级();
this.callOnChange=this.callOnChange.bind(this);
this.callOnRemove=this.callOnRemove.bind(this);
}
callOnChange(e){
this.props.callOnChangeFunc(e,this.props.record);
}
callOnRemove(e){
this.props.callOnRemoveFunc(e,this.props.record);
}
render(){
返回(
{this.props.record.Id}
去除
);
}
}
ReactDOM.render(,document.querySelector(“#app”))
谢谢大家的反馈。这很有帮助。我了解到,如果您使用React行,则需要具有唯一的键。使用过滤器而不是“拼接”也很有帮助。我必须添加更改事件。当我把一个组件组合成多个组件时,我发现它非常有用。我更新了解决方案,以便在删除一行后不会删除输入字段。我还意识到,与AngularReact不同,React只进行单向绑定,每次数据更改都必须通过状态更新。以下是完整的解决方案:。特别感谢用户2340824的持续反馈。
以下是最终代码:
class MineCts extends React.Component{
constructor(props){
super(props);
this.state = {
items:[]
};
this.add = this.add.bind(this);
this.onDataChange = this.onDataChange.bind(this);
this.remove = this.remove.bind(this);
}
render(){
return(
<div>
<div><button onClick={this.add} >Add</button></div>
<div>
This is sample:
{this.state.items.map((record, index)=>{
return(
<DetailTable record ={record} callOnChangeFunc={this.onDataChange} callOnRemoveFunc={this.remove} />
);
})}
</div>
</div>
)
}
onDataChange(e, record)
{
e.preventDefault();
let rows = [...this.state.items];
record[e.target.id]=e.target.value;
rows[record.Id] = record;
this.setState({items:rows})
}
add(e){
let rows = [...this.state.items];
rows.push({Id: new Date().getTime(), Name:null, Counter:null});
this.setState({items:rows})
}
remove(e, record){
e.preventDefault();
let rows = [...this.state.items.filter(x=>x.Id!==record.Id)];
this.setState({items:rows})
}
}
class DetailTable extends React.Component{
constructor(props){
super();
this.callOnChange = this.callOnChange.bind(this);
this.callOnRemove = this.callOnRemove.bind(this);
}
callOnChange(e){
this.props.callOnChangeFunc(e, this.props.record);
}
callOnRemove(e){
this.props.callOnRemoveFunc(e, this.props.record);
}
render(){
return (
<div>
<table>
<tr key={this.props.record.Id} >
{this.props.record.Id}
<td>
<input id="Name" value={this.props.record.Name} onChange={this.callOnChange} /> </td>
<td>
<input id="Counter" value={this.props.record.Counter} onChange={this.callOnChange} /> </td>
<td><button onClick={this.callOnRemove} >Remove</button></td>
</tr>
</table>
</div>
);
}
}
ReactDOM.render(<MineCts />, document.querySelector("#app"))
类MineCts扩展React.Component{
建造师(道具){
超级(道具);
此.state={
项目:[]
};
this.add=this.add.bind(this);
this.onDataChange=this.onDataChange.bind(this);
this.remove=this.remove.bind(this);
}
render(){
返回(
添加
这是一个示例:
{this.state.items.map((记录,索引)=>{
返回(
);
})}
)
}
onDataChange(e,记录)
{
e、 预防默认值();
让行=[…this.state.items];
记录[e.target.id]=e.target.value;
行[record.Id]=记录;
this.setState({items:rows})
}
加(e){
让