React 重复运行函数,但我没有调用它
React runs function repeatedly, but I have not called it
我正在使用 React table (https://github.com/react-tools/react-table) 来呈现 table 的费用。在一栏中,应该有一个 'approve' 费用的按钮。这是这样处理的:
const columns = [
{
Header: "Description",
accessor: "description"
},
{
Header: "Approve",
accessor: d => {
return <button onClick={this.approveExpense(d.id)}>Approve</button>;
},
id: "approved"
}
];
其中 approveExpense 函数定义为:
approveExpense = id => {
fetch(`${apiRoot}expenses_pending/`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Token ${this.props.auth.token}`
},
body: JSON.stringify({
id: id
})
}).then(res => {
if (res.status === 200) {
this.setState({
issues: this.state.expenses.filter(expense => expense.id != id)
});
} else {
console.log("Error");
}
});
};
然而,奇怪的是,当页面加载时,它表现得好像所有这些按钮都被重复按下,每秒多次(直到粉丝开始疯狂并且我停止了反应服务器)。
我是不是在做傻事?
完整 class:
class ExpensePendingAdmin extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
fetch(`${apiRoot}expenses_pending`, {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Token ${this.props.auth.token}`
}
})
.then(response => response.json())
.then(data => {
console.log(data);
this.setState({
expenses: data
});
});
}
approveExpense = id => {
fetch(`${apiRoot}expenses_pending/`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Token ${this.props.auth.token}`
},
body: JSON.stringify({
id: id
})
}).then(res => {
if (res.status === 200) {
this.setState({
issues: this.state.expenses.filter(expense => expense.id != id)
});
} else {
console.log("Error");
}
});
};
render() {
const columns = [
{
Header: "Description",
accessor: "description"
},
{
Header: "Logged At",
id: "loggedAt",
accessor: d =>
moment(d.expense_incur_datetime).format("HH:mm - ddd d/M/YYYY")
},
{
Header: "Amount",
accessor: d => `£${d.amount}`,
id: "amount"
},
{
Header: "Approve",
accessor: d => {
return <button onClick={this.approveExpense(d.id)}>Approve</button>;
},
id: "approved"
},
{
Header: "Paid",
accessor: d => {
console.log(d);
return d.is_unpaid ? "No" : "Yes";
},
id: "paid"
}
];
return (
<div className="container-fluid">
{this.state.expenses ? (
<>
<div className="row">
<div className="col text-center">
<h2>Pending Expenses</h2>
</div>
</div>
<div className="row">
<div className="col">
<ReactTable
data={this.state.expenses}
columns={columns}
minRows="0"
minWidth="50"
showPagination={false}
/>
</div>
</div>
</>
) : (
"LOADING"
)}
</div>
);
}
}
JSX 中的事件处理程序中的方法不需要括号,如果您想传递一个参数,只需将其包装在一个函数中即可:
onClick={() => this.approveExpense(d.id)}
您的代码存在问题,您以错误的方式传递了事件处理程序:
return <button onClick={this.approveExpense(d.id)}>Approve</button>;
通过在你的 JSX 代码中直接使用 this.approveExpense(d.id) 你告诉 javascript 在解释器读取它时立即执行该函数。
相反,您应该在点击时代理函数执行,如下所示:
return <button onClick={(e) => {this.approveExpense(d.id)}}>Approve</button>;
有关如何在 React 中将函数传递给组件的更深入的解释,您可以查看 https://reactjs.org/docs/faq-functions.html
所有其他答案都是正确的,但是您还可以通过使函数具有多个参数集来改进函数调用的语法:
approveExpense = id => ev => {
然后像这样设置访问器渲染:
accessor: d => <button onClick={this.approveExpense(d.id)}>Approve</button>;
函数:this.approveExpense(d.id)
将 return 另一个能够接收另一个参数(这里是点击事件名称 ev
)的函数,并且会像魅力一样工作
你需要像回调函数一样传入approveExpense()函数,所以它只会在你点击的时候触发。
<button onClick={(d) => this.approveExpense(d.id)}>Approve</button>
我正在使用 React table (https://github.com/react-tools/react-table) 来呈现 table 的费用。在一栏中,应该有一个 'approve' 费用的按钮。这是这样处理的:
const columns = [
{
Header: "Description",
accessor: "description"
},
{
Header: "Approve",
accessor: d => {
return <button onClick={this.approveExpense(d.id)}>Approve</button>;
},
id: "approved"
}
];
其中 approveExpense 函数定义为:
approveExpense = id => {
fetch(`${apiRoot}expenses_pending/`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Token ${this.props.auth.token}`
},
body: JSON.stringify({
id: id
})
}).then(res => {
if (res.status === 200) {
this.setState({
issues: this.state.expenses.filter(expense => expense.id != id)
});
} else {
console.log("Error");
}
});
};
然而,奇怪的是,当页面加载时,它表现得好像所有这些按钮都被重复按下,每秒多次(直到粉丝开始疯狂并且我停止了反应服务器)。
我是不是在做傻事?
完整 class:
class ExpensePendingAdmin extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
fetch(`${apiRoot}expenses_pending`, {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Token ${this.props.auth.token}`
}
})
.then(response => response.json())
.then(data => {
console.log(data);
this.setState({
expenses: data
});
});
}
approveExpense = id => {
fetch(`${apiRoot}expenses_pending/`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Token ${this.props.auth.token}`
},
body: JSON.stringify({
id: id
})
}).then(res => {
if (res.status === 200) {
this.setState({
issues: this.state.expenses.filter(expense => expense.id != id)
});
} else {
console.log("Error");
}
});
};
render() {
const columns = [
{
Header: "Description",
accessor: "description"
},
{
Header: "Logged At",
id: "loggedAt",
accessor: d =>
moment(d.expense_incur_datetime).format("HH:mm - ddd d/M/YYYY")
},
{
Header: "Amount",
accessor: d => `£${d.amount}`,
id: "amount"
},
{
Header: "Approve",
accessor: d => {
return <button onClick={this.approveExpense(d.id)}>Approve</button>;
},
id: "approved"
},
{
Header: "Paid",
accessor: d => {
console.log(d);
return d.is_unpaid ? "No" : "Yes";
},
id: "paid"
}
];
return (
<div className="container-fluid">
{this.state.expenses ? (
<>
<div className="row">
<div className="col text-center">
<h2>Pending Expenses</h2>
</div>
</div>
<div className="row">
<div className="col">
<ReactTable
data={this.state.expenses}
columns={columns}
minRows="0"
minWidth="50"
showPagination={false}
/>
</div>
</div>
</>
) : (
"LOADING"
)}
</div>
);
}
}
JSX 中的事件处理程序中的方法不需要括号,如果您想传递一个参数,只需将其包装在一个函数中即可:
onClick={() => this.approveExpense(d.id)}
您的代码存在问题,您以错误的方式传递了事件处理程序:
return <button onClick={this.approveExpense(d.id)}>Approve</button>;
通过在你的 JSX 代码中直接使用 this.approveExpense(d.id) 你告诉 javascript 在解释器读取它时立即执行该函数。 相反,您应该在点击时代理函数执行,如下所示:
return <button onClick={(e) => {this.approveExpense(d.id)}}>Approve</button>;
有关如何在 React 中将函数传递给组件的更深入的解释,您可以查看 https://reactjs.org/docs/faq-functions.html
所有其他答案都是正确的,但是您还可以通过使函数具有多个参数集来改进函数调用的语法:
approveExpense = id => ev => {
然后像这样设置访问器渲染:
accessor: d => <button onClick={this.approveExpense(d.id)}>Approve</button>;
函数:this.approveExpense(d.id)
将 return 另一个能够接收另一个参数(这里是点击事件名称 ev
)的函数,并且会像魅力一样工作
你需要像回调函数一样传入approveExpense()函数,所以它只会在你点击的时候触发。
<button onClick={(d) => this.approveExpense(d.id)}>Approve</button>