I want to calculate the past movements of the balance according to the transactions on the accounting account detail page as a new field on the client side and print it on the table.
export default function App() {
const transactions = [
{
action: "Action 4",
total: 100
},
{
action: "Action 3",
total: -90
},
{
action: "Action 2",
total: 78
},
{
action: "Action 1",
total: -20
}
];
return (
<div>
<table border={1}>
<thead>
<tr>
<th>Action</th>
<th>Total</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
{transactions.map((item, index) => {
const balance = transactions
.slice(0, index 1)
.reduce((a, b) => parseFloat(a) parseFloat(b.total), 0);
return (
<tr>
<td>{item.action}</td>
<td>{item.total}</td>
<td>{balance}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}
In the code here, I did the balance collection process, but it adds up from top to bottom. How should I arrange this process from bottom to top?
I want should be like this
CodePudding user response:
I'd
- keep the transactions originally in chronological order
- use
useMemo
to map them into a new object with the balance too (you could alsoreduce
if you like, but this feels clearer), and reverse them there.
This both allows for clearer code and less work (you do the mapping only once, instead of reduce
ing in the render phase).
const transactions = [
{
action: "Action 1",
total: -20,
},
{
action: "Action 2",
total: 78,
},
{
action: "Action 3",
total: -90,
},
{
action: "Action 4",
total: 100,
},
];
export default function App() {
const transactionsWithBalance = React.useMemo(() => {
let balance = 0;
const withBalance = transactions.map((transaction) => {
balance = transaction.total;
return {
...transaction,
balance,
};
});
return withBalance.reverse();
}, [transactions]);
// Render `transactionsWithBalance` here...
}
CodePudding user response:
Try using .reduceRight
instead of .reduce
: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight