我现在正在教自己做出反应,我有一个查看状态的组件,当添加新项目时,它会将子组件附加到自身。我现在要做的是通过单击删除添加的子组件。但是我似乎无法获得链接的自然事件停止,如果我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;
以及指向我的沙箱的链接
答案 0 :(得分:1)
在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>
)
}
}
答案 1 :(得分:0)
您应该绑定项目的索引以直接删除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>
);
}
这会将索引作为第一个参数绑定到在props中传递的removeItem函数,同时保持对象绑定不变(因此方法的上下文仍然是GenerateInvoice组件。由事件处理程序传递,它将显示为第二个参数。
所以处理程序定义应该是:
removeItem(index, e) {
e.preventDefault();
...your removal code here...
}
最后,子组件中的超级简单事件处理:
<a href="" onClick={props.remove}>Remove</a>
虽然我会使用<button>
元素来删除整个默认事件处理&amp;完全传播。 <a>
应专门用于导航内容。