Ad

Query State In React, And SetState Or Update If Exists

- 1 answer

I am trying to add Transactions to an app in React, and I want to organise these transactions by year, then month, so the structure would be the following:

{
  "2016" : {
    "january": {
      "transaction1": transaction,
      "transaction2": transaction,
      "transaction3": transaction
    },
    "february" : {
      "transaction1": transaction,
      "transaction2": transaction,
      "transaction3": transaction
    }
  }
}

I have a function in my App that receives a transaction object, which I then want to add to the transactions state to the relevant year/month.

addTransaction(transaction) {
    const monthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"];
    var year = (new Date()).getFullYear();
    var month = monthNames[(new Date()).getMonth()];
    console.log(
      this.state.transactions != null;
    );
    // check year exists?
    // add if necessary
    // check month exists?
    // add if necessary
  }

What I am trying to work out is:

  • How can i query whether the year exists in the transactions state object
  • I then need to apply it to the correct year and month if it does exist, or
  • Add the new year and month if it doesn't

UPDATE: I have updated addTransaction, and am trying to create the year (not adding the month in yet) and then add the transaction to that, but it's not creating the year and I am getting Uncaught TypeError: Cannot set property 'transaction-1453842528740' of undefined

addTransaction(transaction) {
    var timestamp = (new Date()).getTime();
    const monthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"];
    var year = (new Date()).getFullYear();
    var month = monthNames[(new Date()).getMonth()];

    if (year in this.state.transactions) {
      // add to year
    } else {
      this.state.transactions[year]['transaction-' + timestamp] = transaction;
    }

    this.setState({
      transactions: { [year]: this.state.transactions[year] }
    });
  }

Thanks in advance.

Ad

Answer

This is the way you'd do it if you like mutating your objects:

const transactions = this.state.transactions;
// get or create the year object
const yearObject = transactions[year] || (transactions[year] = {});
// get or create the month object
const monthObject = yearObject[month] || (yearObject[month] = {});
// add the transaction
const transactionId = `transaction-${timestamp}`;
monthObject[transactionId] = transaction;
this.setState({ transactions });

And this is how you'd do it in an immutable style (which would let you make your component pure:

const transactions = this.state.transactions;
// get or create the year object
const yearObject = transactions[year] || {};
// get or create the month object
const monthObject = yearObject[month] || {};
// add the transaction
const transactionId = `transaction-${timestamp}`;

const newTransactions = {
    // copy the old object
    ...transactions,
    // assign a copy of the year object
    [year]: {
        // copy the old year object
        ...yearObject,
        // assign a copy of the month object
        [month]: {
            // copy the old month object
            ...monthObject,
            // add the new transaction
            [transactionId]: transaction
        }
    }
};

// assign our new object
this.setState({ transactions: newTransactions });
Ad
source: stackoverflow.com
Ad