背景
我在写作的反应应用中遇到了问题。我一直试图从表中删除一行,但我一直在
setState未定义
所以基本上我就是这样设置的。
此函数将从表中删除行。 我没有测试过这个因为我一直得到
未定义的错误
setState
function removeRow(id) {
this.setState(state => {
state.tableData.splice(id, 1);
return {tableData: state.tableData};
});
}
问题
当tr
点火时table
如何正确删除onClick method
state
,以便render
更改并table
{{1}没有被删除的tr
的话?
实施例
这是调用onClick
的{{1}}方法。
removeRow()
这就是它们在一起的样子,
<td><a href="#" onClick={() => { removeRow(tableData[key].id) }}>Delete</a></td>
我还尝试将var requests = [
{"id":1, "title":"Request from Nancy","updated_at":"2015-08-15 12:27:01 -0600","created_at":"2015-08-12 08:27:01 -0600","status":"Denied"}
]
class TableDisplay extends React.Component {
constructor() {
super();
this.state = {
tableData: requests
}
}
render() {
const {tableData} = this.props;
return (
<div className="table-wrapper">
<div><table className="table">
<tr className="separate"><td>Title</td><td>Status</td>
<td>Created</td><td>Updated</td><td>Delete</td></tr>
{Object.keys(tableData).map(function(key) {
function removeRow(id) {
this.setState(state => {
state.tableData.splice(id, 1);
return {tableData: state.tableData};
});
}
return // removed extra code to make it easy to read.
<td><a href="#" onClick={() => { removeRow(tableData[key].id) }}>Delete</a></td>
</tr>;
})}
</table>
</div>
</div>
);
}
}
直接移到removeRow()
下方constructor
上方,但是当我这样做时,当onClick触发时,removeRow()会抛出错误,
removeRow未定义。
render()
答案 0 :(得分:3)
您的组件存在一些问题,即您不会在remove函数中绑定上下文(因此setState
未定义)。尝试这样的事情:
const TableRow = (props) => (
<tr>
<td>{props.title}</td>
<td>{props.status}</td>
<td>{props.updated_at}</td>
<td>{props.created_at}</td>
<td><a href="#" onClick={() => props.remove(props.index)}>Delete</a></td>
</tr>
)
class TableDisplay extends React.Component {
constructor() {
super();
this.state = {
tableData: [{
"id":1,
"title":"Request from Nancy",
"updated_at":"2015-08-15 12:27:01 -0600",
"created_at":"2015-08-12 08:27:01 -0600",
"status":"Denied"
}]
};
}
remove(index) {
this.setState({
tableData: this.state.tableData.filter((row, i) => i !== index)
});
}
render() {
return (
<div className="table-wrapper">
<div>
<table className="table">
<tbody>
{
this.state.tableData.map((row, i) => {
return (
<TableRow
title={row.title}
id={row.id}
updated_at={row.updated_at}
created_at={row.created_at}
status={row.status}
remove={this.remove.bind(this)}
index={i}
key={i} />
);
})
}
</tbody>
</table>
</div>
</div>
);
}
}
ReactDOM.render((
<TableDisplay />
), document.getElementById("app"));
答案 1 :(得分:2)
这种情况失去了。
您可以将功能绑定到this
。
class TableDisplay extends React.Component {
constructor() {
super();
this.state = {
tableData: requests
}
//ADD THIS LINE
this.removeRow = this.removeRow.bind(this);
}
// I have to remove "function" from the declaration or the app wont render from parse error.
removeRow(id) {
this.setState(state => {
state.tableData.splice(id, 1);
return {tableData: state.tableData};
});
}
......
<a href="#" onClick={() => { this.removeRow(tableData[key].id) }}
或者,如果您使用的是ES6 Stage 2 preset
,则可以使用箭头功能
class TableDisplay extends React.Component {
constructor() {
super();
this.state = {
tableData: requests
}
}
// I have to remove "function" from the declaration or the app wont render from parse error.
removeRow = (id) => {
this.setState(state => {
state.tableData.splice(id, 1);
return {tableData: state.tableData};
});
}
......
答案 2 :(得分:1)
当你在第二个解决方案中调用removeRow
时,你需要像this.removeRow
一样调用它,因为它在渲染函数之外。您还需要绑定它以便访问setState
。为此,您可以使用箭头功能
class TableDisplay extends React.Component {
constructor() {
super();
this.state = {
tableData: requests
}
}
// I have to remove "function" from the declaration or the app wont render from parse error.
removeRow = (id) => {
this.setState(state => {
state.tableData.splice(id, 1);
return {tableData: state.tableData};
});
}
render() {
const {tableData} = this.props;
return (
<div className="table-wrapper">
<div><table className="table">
<tr className="separate"><td>Title</td><td>Status</td>
<td>Created</td><td>Updated</td><td>Delete</td></tr>
{Object.keys(tableData).map(function(key) {
return // removed extra code to make it easy to read.
<td><a href="#" onClick={() => { this.removeRow(tableData[key].id) }}>Delete</a></td>
</tr>;
}.bind(this))}
</table>
</div>
</div>
);
}
}
答案 3 :(得分:1)
**Put removeRow method above render() and give current scope reference as var that = this; **
class TableDisplay extends React.Component {
constructor() {
super();
this.state = {
selectValue: 'all',
tableData: requests
}
}
removeRow() {
this.setState(state => {
state.tableData.splice(id, 1);
return {tableData: state.tableData};
});
}
render() {
const {selectValue} = this.props;
const {tableData} = this.props;
var that = this;
return (
<div className="table-wrapper">
<div><table className="table">
<tr className="seperate"><td>Title</td><td>Status</td><td>Created</td><td>Updated</td><td>Delete</td></tr>
{Object.keys(tableData).map(function(key) {
let styling = "bg-plain";
let hidden = "hidden";
let tds = document.querySelectorAll(".table td");
let trs = document.querySelectorAll(".table tr");
function showHiddenRows() {
for (var i = 0; i < trs.length; i++) {
trs[i].classList.remove("hidden");
}
}
function setStyle() {
if (tableData[key].status === "Approved") {
styling = "bg-success";
} else if (tableData[key].status === "Denied") {
styling = "bg-danger";
}
for (var i = 0; i < tds.length; i++) {
if (tds[i].innerText === "Approved") {
tds[i].parentNode.setAttribute('class', 'bg-success')
} else if (tds[i].innerText === "Denied") {
tds[i].parentNode.setAttribute('class', 'bg-danger')
}
}
}
function filterTable(fa, fb) {
for (var i = 0; i < tds.length; i++) {
if (tds[i].innerText === fa) {
tds[i].parentNode.setAttribute('class', 'hidden')
} else if (tds[i].innerText === fb) {
tds[i].parentNode.setAttribute('class', 'hidden')
}
}
}
if (selectValue === "all") {
showHiddenRows();
setStyle();
} else if (selectValue === "approved") {
showHiddenRows();
setStyle();
filterTable("Pending", "Denied");
} else if (selectValue === "pending") {
showHiddenRows();
setStyle();
filterTable("Approved", "Denied");
} else if (selectValue === "denied") {
showHiddenRows();
setStyle();
filterTable("Approved", "Pending");
}
{console.log(tableData[key].id)}
return <tr key={tableData[key].id} id={tableData[key].id} className={styling}>
<td>{tableData[key].title}</td>
<td>{tableData[key].status}</td>
<td>{tableData[key].created_at.slice(0, 10)}</td>
<td>{tableData[key].updated_at.slice(0, 10)}</td>
<td><a href="#" onClick={() => { that.removeRow() }}>Delete</a></td>
</tr>;
})}
</table>
</div>
</div>
);
}
}