我想在map函数中调用函数里面的render render方法。我的示例代码:
module.exports = {
// ...
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
}
}
}
并调用this.balance()
render() {
return (
{this.state.studentLedger.map((post, i) => (
<tr key={i}>
<td>{ i+1 }</td>
<td>{ post.transaction_date }</td>
<td>{ post.particular }</td>
<td>{ post.dr }</td>
<td>{ post.cr }</td>
<td>{(post) => this.balance(post.dr, post.cr)} { this.state.balance }</td>
</tr>
))}
)}
我得到了balance(dr, cr){
this.state.balance ? this.setState({balance : (this.state.balance + dr)}) : this.setState({balance : (this.state.balance - cr)});
}
。我怎样才能实现这个功能。
答案 0 :(得分:3)
您收到该错误的原因是,您不是仅调用this.balance
并使用{}
评估其返回值(可能输出string
),而是创建新的箭头函数,你不是在打电话,而是评估它。
这一行:
<td>{ (post) => this.balance(post.dr, post.cr) } { this.state.balance }</td>
应该是:
<td>{ this.balance(post.dr, post.cr) } { this.state.balance }</td>
假设this.balance
只是一个函数,它返回您想要在组件中显示的文本,但情况并非如此,因为您没有从中返回任何内容。< / p>
更糟糕的是,您不应该从setState
致电render
。 render
不应导致任何副作用,在您的情况下,调用setState
会触发重新渲染,再次调用setState
,这将... ...基本上,您将结束无限循环。
我想您只想显示余额随时间的变化,因此为此,您不需要更新状态。您可以保持原样,只保留当前余额和Array
个交易。然后,当您在render
内循环浏览它们时,您将更新本地 balance
变量,该变量将显示在每一行上,如下所示:
class Balance extends React.Component {
constructor(props) {
super(props);
this.state = { balance: 2000, studentLedger: [{
transaction_date: '5 MAY 2018',
dr: 1200,
cr: 0,
}, {
transaction_date: '1 MAY 2018',
dr: 0,
cr: 100,
}, {
transaction_date: '20 APR 2018',
dr: 0,
cr: 100,
}, {
transaction_date: '10 APR 2018',
dr: 800,
cr: 0,
}, {
transaction_date: '1 APR 2018',
dr: 0,
cr: 600,
}, {
transaction_date: '22 MAR 2018',
dr: 0,
cr: 200,
}, {
transaction_date: '1 MAR 2018',
dr: 1000,
cr: 0,
}, {
transaction_date: '1 JAN 2018',
dr: 0,
cr: 0,
}],
};
}
render() {
const studentLedger = this.state.studentLedger;
const totalEntries = studentLedger.length;
// Balance is the current amount:
let balance = this.state.balance;
const rows = studentLedger.map((post, i) => {
// We start displaying the current amount:
const currentBalance = balance;
// And we update it for the next iteration (note the signs are the opposite of
// what you might think at first):
balance += -post.dr || post.cr;
return (
<tr key={ i }>
<td>{ totalEntries - i }</td>
<td>{ post.transaction_date }</td>
<td>{ post.dr }</td>
<td>{ post.cr }</td>
<td>{ currentBalance }</td>
</tr>
);
});
return (
<table>
<tr>
<th>ID</th>
<th>DATE</th>
<th>DR</th>
<th>CR</th>
<th>BALANCE</th>
</tr>
{ rows }
</table>
);
}
}
ReactDOM.render(<Balance />, document.getElementById('app'));
&#13;
body {
font-family: monospace;
}
table {
border: 2px solid #000;
border-collapse: collapse;
text-align: right;
width: 100%;
}
th,
td {
border: 2px solid #000;
padding: 8px 16px;
width: 20%;
}
th {
background: #000;
color: #FFF;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
如果您愿意,还可以更新constructor
中的状态,以便每个条目都包含计算的余额。如果您使用的是Redux,您可能希望在reducer中执行此操作,或者您甚至可以考虑使用Reselect和选择器:http://blog.rangle.io/react-and-redux-performance-with-reselect/
答案 1 :(得分:1)
使用此代码以正确的方式显示学生平衡,而不通过在渲染中调用setstate进入无限循环。
除此之外,你需要做的是你必须写balance(i, dr,cr){...}
,它会返回第i个学生的正确平衡。并在设置state.studentLedger的值时立即调用setStudentBalance()。
setStudentBalance(){
let balances = this.state.studentLedger.map((post, i) =>{
return this.balance(i, post.dr, post.cr)
})
this.setState({studentBalances:balances})
}
render() {
return (
{this.state.studentLedger.map((post, i) =>(
<tr key={i}>
<td>{ i+1 }</td>
<td>{ post.transaction_date }</td>
<td>{ post.particular }</td>
<td>{ post.dr }</td>
<td>{ post.cr }</td>
<td>{this.state.balance[i] }</td>
</tr>
)
)}
)}