I have an app which logs income, expenditure and transactions. Each has their own respective component, and within that component, I want to list all of the financial data, so in the transactions, list each transaction for a calendar month and it’s details, value etc.
on the dashboard, I want to render: the total value for all transactions, expenditure, and income. Then available to spend, by subtracting expenditure and transactions from income.
The financial data is from Redux store, then on the dashboard component, I have initialised state for the totals:
constructor(props) {
super(props);
this.state = {
expenditureTotal: 0,
incomeTotal: 0,
transactionsTotal: 0
}
}
I have a sumTotal method which I pass each chunk of data to calculate the totals:
sumTotal(data) {
return data
.map((obj) => { return obj.amount; })
.reduce((prev, next) => { return prev += next; }, 0);
}
I need to update the component state with these totals so I can then calculate and display the remaining balance, but I am not sure of the appropriate way to update the state values, as the relevant values are only calculated on render via the sumTotal
method. How to I then setState
with the new totals, to then pass down to the Remaining Balance component (which I need to create).
Below is the relevant parts of the component, any help would be amazing. Thank you.
class Transactions extends Component {
constructor(props) {
… as code sample above
}
componentWillMount() {
fetch data from redux
}
sumTotal(data) {
… as code sample above
}
render() {
const { transactions, expenditure, income } = this.props;
const { transactionsTotal, expenditureTotal, incomeTotal } = this.state;
if (!transactions || !expenditure || !income) {
return (
<div>
<p>Loading...</p>
</div>
)
}
return (
<section>
<h2>Transactions <Link className="actionlink" to="/transactions/add">Add</Link></h2>
<table className="financials -transactions">
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th className="activefilter">Amount</th>
<th className="actions"> </th>
<th className="actions"> </th>
</tr>
</thead>
<tbody>
{this.props.transactions.map(
(transaction, i) =>
<Transaction {...this.props} key={i} transaction={transaction} delete={this.handleDelete} />
)}
</tbody>
</table>
<section className="sumtotal">
<Total value={this.sumTotal(transactions)} type="Transactions" />
<Total value={this.sumTotal(expenditure)} type="Expenditure" />
<Total value={this.sumTotal(income)} type="Income" />
<div className="remaining">
Display state totals calculation here
</div>
</section>
</section>
);
}
}
function mapStateToProps(state) {
return {
transactions: state.transactions.all,
expenditure: state.expenditure.all,
income: state.income.all
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(actionCreators, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(Transactions);
mapStateToProps
. Then write acomponentWillReceiveProps
in your component. Inside that, update the state based on new props – Deadfish