Javascript 在React中查询状态,并设置状态或更新(如果存在)
我正在尝试将交易添加到React中的应用程序中,我希望按年度,然后按月组织这些交易,因此结构如下所示:Javascript 在React中查询状态,并设置状态或更新(如果存在),javascript,reactjs,Javascript,Reactjs,我正在尝试将交易添加到React中的应用程序中,我希望按年度,然后按月组织这些交易,因此结构如下所示: { "2016" : { "january": { "transaction1": transaction, "transaction2": transaction, "transaction3": transaction }, "february" : { "transaction1": transaction,
{
"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
}
我想做的是:
- 如何查询
状态对象中是否存在年份交易
- 然后,我需要将其应用于正确的年份和月份(如果确实存在),或者
- 如果没有,则添加新年和月份
addTransaction
,并且正在尝试创建年份(尚未添加月份),然后将该事务添加到该年份,但它没有创建年份,并且我得到了Uncaught TypeError:无法设置未定义的属性“transaction-1453842528740”
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] }
});
}
提前感谢。这些是JavaScript问题,我将在下面回答。在ReactJS上下文中,只能更新组件状态中的顶级对象。所以在你的例子中,你不能只更新“一月”;您必须完全替换“2016”
a = {
"2016" : {
"january": {
"transaction1": 1,
"transaction2": 2,
"transaction3": 3
},
"february" : {
"transaction1": 4,
"transaction2": 5,
"transaction3": 6
}
}
}
!!a["2016"]
返回真值,以及
!!a["2015"]
返回false
只需创建一个新的顶级“2016”对象。这意味着将结构的修改版本传递给setState()。这可能看起来效率低下,但它确实有效。这些是JavaScript问题,我将在下面回答。在ReactJS上下文中,只能更新组件状态中的顶级对象。所以在你的例子中,你不能只更新“一月”;您必须完全替换“2016”
a = {
"2016" : {
"january": {
"transaction1": 1,
"transaction2": 2,
"transaction3": 3
},
"february" : {
"transaction1": 4,
"transaction2": 5,
"transaction3": 6
}
}
}
!!a["2016"]
返回真值,以及
!!a["2015"]
返回false
只需创建一个新的顶级“2016”对象。这意味着将结构的修改版本传递给setState()。这可能看起来效率低下,但它确实有效。如果您喜欢改变对象,您可以这样做:
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 });
如果你喜欢改变你的对象,你可以这样做:
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 });
在操作符中有一个
,用于检查键的存在。!!
看起来很混乱,可能有误报。非常感谢John,肯定能做到这一点,但是我得到了未捕获的类型错误:无法用更新的代码设置未定义的
的属性“transaction-1453842661026”。(已使用更新的代码编辑了我的原始帖子。我使用的代码没有设置年份和事务。感谢您的帮助。您似乎试图直接设置this.state.transactions,这在ReactJS中不起作用。您必须使用此.setState({transactions:…});为事务提供一个完整的对象。该对象是this.state.transactions的副本,可以根据需要进行修改。我刚刚在另一个建议的解决方案中看到了@Brandon的“不可变”版本;我建议这样做。
操作符中有一个,用于检查键的存在。!!
看起来很混乱,可能有误报。谢谢很多John,肯定达到了这一点,但是我得到了未捕获的TypeError:无法使用更新的代码设置未定义的属性“transaction-1453842661026”。(已使用更新的代码编辑了我的原始帖子。我使用的代码没有设置年份和事务。感谢您的帮助。您似乎试图直接设置this.state.transactions,这在ReactJS中不起作用。您必须使用此.setState({transactions:…});为事务提供一个完整的对象。该对象是this.state.transactions的副本,可以根据需要进行修改。我刚刚在另一个建议的解决方案中看到了@Brandon的“不可变”版本;我建议这样做。您只需将setState
行移到else
块中即可;您不应该操纵state direcThy!您只需将setState
行移动到else
块中即可;您不应该直接操纵状态!太好了,谢谢您Brandon:)我可以问一下,关于复制现有事务/年/月对象的技术,使用…事务等…这叫什么?React文档中是否有关于这一点的内容,以便我可以阅读?再次感谢。这是JavaScript ES7语法。我相信它被称为object spread运算符。根据您的代码示例,看起来您正在使用Babel,因此,只要您启用了它,并且您可以在他们的网站上阅读有关语法的信息,它就应该可以工作。谢谢您-是的,使用Babel。完美,谢谢您Brandon:)我可以问一下,关于复制现有事务/年/月对象的技术,使用…事务等…这叫什么?React文档中是否有关于这一点的内容,以便我可以阅读?再次感谢。这是JavaScript ES7语法。我相信它被称为object spread运算符。根据您的代码示例,看起来您正在使用Babel,因此,只要您启用了它,并且您可以在他们的网站上阅读有关语法的内容,它就应该可以工作。谢谢您——是的,使用Babel。