2016-01-25 44 views
0

我正在尝试将事务添加到React中的应用程序,并且我希望按年份组织这些事务,因此结构将如下所示:在React中查询状态,并设置状态或更新(如果存在)

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

我在我的应用程序中有一个函数,它接收一个事务对象,然后我想将事务状态添加到相关的年/月。

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 
    } 

什么,我试图找出是:

  • 我如何查询是否存在于transactions状态对象的年份
  • 然后我需要把它应用到正确的年份和月份如果它确实存在,或
  • 添加新的年份和月份,如果它不

UPDATE: 我已经更新addTransaction,并想创建年(在不增加每月还),然后将交易补充,但它不是在创建一年,我得到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] } 
    }); 
    } 

提前致谢。

+1

你可以只移动了'setState'线到你的'else'块;!你不应该直接操作状态 – Mathletics

回答

2

这是你做,如果你喜欢你的变异对象的方式:

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 }); 

这是你会怎么做,在一个不变的风格(这将让你让你的成分纯净:

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 }); 
+0

完美,谢谢布兰登:)我能问,关于技术复制现有交易/年/月对象与......交易等......这叫做什么? React文档中是否有任何内容可供阅读?再次感谢。 – zeKoko

+0

这是JavaScript ES7语法。对象传播运算符我相信它被调用。根据你的代码示例,它看起来像你使用的是Babel,所以只要你启用它就可以工作,你可以阅读他们网站上的语法。 – Brandon

+0

谢谢 - 是的,使用Babel。 – zeKoko

2

这些是JavaScript问题,我将在下面回答。在ReactJS上下文中,您只能更新组件状态内的顶级对象。所以在你的例子中,你不能只更新“一月”;你必须完全取代“2016”。

  1. How can i query whether the year exists in the transactions state object
!!object[key] 

返回当存在。因此,例如,

a = { 
    "2016" : { 
    "january": { 
     "transaction1": 1, 
     "transaction2": 2, 
     "transaction3": 3 
    }, 
    "february" : { 
     "transaction1": 4, 
     "transaction2": 5, 
     "transaction3": 6 
    } 
    } 
} 
!!a["2016"] 

回报真实,并

!!a["2015"] 

回报

  1. 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

只需创建一个新的顶级“2016”对象。这意味着将结构的修改版本传递给setState()。它可能看起来效率低下,但它起作用。

+0

有一个'in'运营商咨询是否存在的关键''!!看起来混乱,可能有假阴性。 – zerkms

+0

非常感谢约翰,绝对到达那里,但我得到'遗漏的类型错误:无法与更新的代码设置属性“交易1453842661026” undefined'的。 (编辑了我原来的职位有更新的代码。我使用的代码没有设置一年的交易。感谢您的帮助。 – zeKoko

+0

你似乎在试图设置** ** this.state.transactions直接,从而赢得“吨ReactJS工作,你必须使用** this.setState({交易:...}); **提供了**交易一个完整的对象**该对象this.state.transactions的副本,根据你的需要修改 –