点击链接去除子组件
问题描述:
我在教自己做出反应的时候,我有一个组件查看状态,当添加一个新项目时,它将一个子组件添加到它自己。我现在要做的是通过点击删除添加的子组件。不过,我似乎无法得到链接的自然事件停止,如果我做e.preventDefault()
我得到preventDefault不是未定义的函数。点击链接去除子组件
下面是我的代码,
import React, { Component } from 'react';
import InvoiceForm from './InvoiceForm';
import InvoiceItemForm from './InvoiceItemForm';
class GenerateInvoice extends Component {
constructor(props) {
super(props);
this.state = {
invoice: {
items : []
}
};
this.onAddChild = this.onAddChild.bind(this);
this.removeItem = this.removeItem.bind(this);
}
render() {
const children = [];
for (var i = 0; i < this.state.invoice.items.length; i += 1) {
children.push(
<InvoiceItemForm
key={i}
number={i}
remove={this.removeItem} />
);
}
return(
<div>
<a href="" onClick={this.onAddChild}>Add New Item</a>
{children}
</div>
)
}
removeItem = (e, itemIndex) => {
e.stopPropagation();
alert("..removing...");
// let invoice = this.state.invoice;
// let updatedItems = this.state.invoice.items.splice(index, 1); //remove element
// let updateInvoice = { ...invoice, items:updatedItems}
// this.setState({ invoice }); //update state
}
onAddChild = (e) => {
e.preventDefault();
let invoice = this.state.invoice;
// creates an updated version of the items without changing the original value
let updatedItems = invoice.items.push({ 'id': 'INV001' });
// creates a new version of the invoice with the updated items
let updateInvoice = { ...invoice, items: updatedItems };
// update the invoice on the state to the new version
this.setState({ invoice });
}
}
出口默认GenerateInvoice;
子组件
import React from 'react';
const InvoiceItemForm = (props) => {
console.log(props);
return(
<div>
<p>Hello {props.number}</p>
<a href="" onClick={props.remove(props.number)}>Remove</a>
</div>
)
}
export default InvoiceItemForm;
和我的沙盒的链接,
答
在InvoiceItemForm
组件,onClick={props.remove(props.number)}
,只有在这里你有参照事件对象。
你可以改变的东西,如:
onClick={(e) => {
e.preventDefault();
props.remove(props.number);
}}
编辑:
如果你想避免创建一个函数每个渲染,你可以使用类似:
class InvoiceItemForm extends React.Component {
handleClick = (e) => {
e.preventDefault();
this.props.remove(props.number);
}
render() {
console.log(this.props);
return(
<div>
<p>Hello {this.props.number}</p>
<a href="" onClick={this.handleClick}>Remove</a>
</div>
)
}
}
答
您应该绑定项目的索引以直接删除removeItem
方法。
重构渲染方法:
render() {
return(
<div>
<a href="" onClick={this.onAddChild}>Add New Item</a>
{this.state.invoice.items.map((item, index) => {
return (
<InvoiceItemForm
key={index}
number={index}
remove={this.removeItem.bind(null, index)}
/>
);
})}
</div>
);
}
这将结合指数作为第一参数在道具传递的的removeItem功能,同时使对象的方法结合不变(这样的上下文。仍然在GenerateInvoice组件时,该事件由事件处理程序通过,将显示为第二个参数
所以处理器定义应该是:
removeItem(index, e) {
e.preventDefault();
...your removal code here...
}
最后是超级简单事件的子组件处理:
<a href="" onClick={props.remove}>Remove</a>
虽然我会用一个<button>
元素,而不是删除整个默认事件共处理&传播。 <a>
应该专门用于导航内容。
这可能是我曾经困惑过的,这是否会在每次重新渲染时创建一个新函数,因此效率低下? – Udders
你说得对。看我的编辑。我不得不说,在我看来,创建一个新的函数,每个渲染没有那么糟糕,避免它是一个微观优化。 –