Javascript 如何在React中按值传递而不是按引用传递?
我有以下文件,LookupPage.jsx和AccountDetails.jsx 查找中Javascript 如何在React中按值传递而不是按引用传递?,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,我有以下文件,LookupPage.jsx和AccountDetails.jsx 查找中 this.updateCustomer = (customer) => { if(JSON.stringify(customer.address) !== JSON.stringify(this.state.activeAccount.customer.address)) { console.log('address changed'); cu
this.updateCustomer = (customer) => {
if(JSON.stringify(customer.address) !== JSON.stringify(this.state.activeAccount.customer.address)) {
console.log('address changed');
customer.update_address = true;
customer.address.source = 'user';
}
return fetch(
`${API_ENDPOINT}/customer/${customer.id}/`,
{
method: 'PATCH',
headers: {
'Authorization': 'Token ' + this.props.session_token,
'Content-Type': 'application/json',
},
body: JSON.stringify(customer),
}
).then(restJSONResponseToPromise).then(responseJSON => {
if(responseJSON.results){
console.log('update customers client side.')
}
}, clearSessionIfInvalidToken(this.props.clearSession));
};
<AccountsDetailModal
show={this.state.showAccountDetail}
close={this.toggleAccountDetail}
customer={this.state.activeAccount.customer}
updateCustomer={this.updateCustomer}
/>
当我更新客户地址时,它正在更新活动帐户地址,因此它似乎是通过引用传递的。我只想在客户地址更改/与原始地址不同时更新客户地址。我将如何修改代码来实现这一点?您可以通过以下方式在JS中按值传递任何对象(无论是否使用React):
JSON.parse(JSON.stringify(myObject))
作为参数而不是对象本身
本质上,这将只是克隆对象并传递其副本,因此您可以在不影响原始对象的情况下任意操纵副本
请注意,如果对象包含函数,这将不起作用,它将只复制属性。(在您的示例中,这应该很好。)您可以通过以下方式通过JS中的值传递任何对象(无论是否使用React):
JSON.parse(JSON.stringify(myObject))
作为参数而不是对象本身
本质上,这将只是克隆对象并传递其副本,因此您可以在不影响原始对象的情况下任意操纵副本
请注意,如果对象包含函数,这将不起作用,它将只复制属性。(在你的例子中,这应该很好。)我将把我的两分钱放在这里: 首先,这并不是真正特定于
React
,而是一个与JS相关的问题
其次,当涉及到反应时,针对内部状态设置道具被认为是一种不好的做法。考虑到您的特定场景,确实没有必要这样做。我指的是
this.setState({customer:this.props.customer})代码>
因此,谈到您的问题,您出现引用问题的原因是因为您在代码中的某些点上修改了原始传入对象。例如,如果我看:
this.updateCustomer = (customer) => {
if(JSON.stringify(customer.address) !== JSON.stringify(this.state.activeAccount.customer.address)) {
console.log('address changed');
customer.update_address = true;
customer.address.source = 'user';
}
};
您正在修改argument对象的原始道具,该道具很可能在组件的其他方法中传递。因此,要克服这一点,您可以:
const updatedCustomer = Object.assign({}, customer, {
update_address: true
});
您可以在API调用中传入updatedCustomer
Object.assign()
不会对传入的对象执行操作,但会返回一个新对象,因此您可以确保在应用程序中的任何时候都不会更改原始对象
注意:对象。赋值将对普通对象有效,而不是嵌套对象。因此,如果您想实现类似的功能,也可以在嵌套对象属性上使用。我将在这里列出我的两分钱:
首先,这并不是真正特定于React
,而是一个与JS相关的问题
其次,当涉及到反应时,针对内部状态设置道具被认为是一种不好的做法。考虑到您的特定场景,确实没有必要这样做。我指的是
this.setState({customer:this.props.customer})代码>
因此,谈到您的问题,您出现引用问题的原因是因为您在代码中的某些点上修改了原始传入对象。例如,如果我看:
this.updateCustomer = (customer) => {
if(JSON.stringify(customer.address) !== JSON.stringify(this.state.activeAccount.customer.address)) {
console.log('address changed');
customer.update_address = true;
customer.address.source = 'user';
}
};
您正在修改argument对象的原始道具,该道具很可能在组件的其他方法中传递。因此,要克服这一点,您可以:
const updatedCustomer = Object.assign({}, customer, {
update_address: true
});
您可以在API调用中传入updatedCustomer
Object.assign()
不会对传入的对象执行操作,但会返回一个新对象,因此您可以确保在应用程序中的任何时候都不会更改原始对象
注意:对象。赋值将对普通对象有效,而不是嵌套对象。因此,如果您想实现类似的功能,也可以在嵌套对象属性上使用。您不能更改参数在JS中的传递方式(对象->“通过引用”)。您是否偶然发现了可变函数与不可变/纯函数?这两种函数的可能重复与React无关,而与javascript处理变量的方式有关。有关更多信息,请参考上面关于“按引用传递或按值传递”的链接。我最好的猜测是我必须更新到componenetDidMount,因此当我设置客户时,它将是道具对象的副本,而不是原始道具对象。我该怎么做?我试过这么做,但还是没有成功。this.setState({customer:{…this.props.customer,update_address:false}});您不能更改参数在JS中的传递方式(对象->“通过引用”)。您是否偶然发现了可变函数与不可变/纯函数?这两种函数的可能重复与React无关,而与javascript处理变量的方式有关。有关更多信息,请参考上面关于“按引用传递或按值传递”的链接。我最好的猜测是我必须更新到componenetDidMount,因此当我设置客户时,它将是道具对象的副本,而不是原始道具对象。我该怎么做?我试过这么做,但还是没有成功。this.setState({customer:{…this.props.customer,update_address:false}});如果您能更详细地解释发生了什么,为什么会发生,以及这与React无关的事实,以及与JS在传递/修改时处理原语/对象的方式有关的一切……这将传递一个新对象(在许多情况下,但并不总是一个副本)每个参考-不太可靠/不推荐,但在许多其他情况下,它也不起作用,例如NaN、无穷大、符号等@cale_b更新以更详细地解释如果您更详细地解释发生了什么、为什么发生以及这与React无关这一事实,那将是非常棒的,一切都与JS处理原语/obj的方式有关