Javascript 使用键简化对象的设置值
有没有办法简化以下代码?可能是通过使用下划线js,我浏览了文档,但找不到任何有助于我解决动态键值对的问题 对象:Javascript 使用键简化对象的设置值,javascript,reactjs,underscore.js,Javascript,Reactjs,Underscore.js,有没有办法简化以下代码?可能是通过使用下划线js,我浏览了文档,但找不到任何有助于我解决动态键值对的问题 对象: this.state = { media : { video : "", photos : [{ title : "Storefront", url : "https://cdn.filepicker.io/api/file/cHyLd9KtSNibpsGl
this.state = {
media : {
video : "",
photos : [{
title : "Storefront",
url : "https://cdn.filepicker.io/api/file/cHyLd9KtSNibpsGlQsny",
category : {
interior : false,
exterior : true,
closeup : false
},
display : {
preview : false,
featured : true,
none : false
},
size : "800 x 600",
attribution_link : "",
attribution_text : "",
description : ""
},
{
...
}]
}
}
我正在使用react,在调用handleDisplayClick(e)方法时,e将具有密钥名称,我需要将其更新为true,其余的更新为false
handleDisplayClick=(e)=>{
var stateCopy=Object.assign({},this.state);
如果(e==“预览”){
stateCopy.media.photos[this.state.media.selectedMediaIndex].display.preview=true;
stateCopy.media.photos[this.state.media.selectedMediaIndex].display.featured=false;
stateCopy.media.photos[this.state.media.selectedMediaIndex].display.none=false;
}
否则如果(e==“特色”){
stateCopy.media.photos[this.state.media.selectedMediaIndex].display.preview=false;
stateCopy.media.photos[this.state.media.selectedMediaIndex].display.featured=true;
stateCopy.media.photos[this.state.media.selectedMediaIndex].display.none=false;
}
否则{
stateCopy.media.photos[this.state.media.selectedMediaIndex].display.preview=false;
stateCopy.media.photos[this.state.media.selectedMediaIndex].display.featured=false;
stateCopy.media.photos[this.state.media.selectedMediaIndex].display.none=true;
}
此.setState(状态副本);
}
识别模式并避免重复代码。例如,无需反复访问stateCopy.media.photos[this.state.media.selectedMediaIndex]
。只需将值赋给变量并使用该变量即可
下面是一个较短的实现:
// assuming `e` is either "preview", "featured" or "none"
const photo = stateCopy.media.photos[this.state.media.selectedMediaIndex];
['preview', 'featured', 'none'].forEach(
property => photo.display[property] = property === e
);
或者没有循环:
// assuming `e` is either "preview", "featured" or "none"
Object.assign(
stateCopy.media.photos[this.state.media.selectedMediaIndex],
{
preview: e === 'preview',
featured: e === 'featured',
none: e === 'none',
}
);
还要注意,
var stateCopy=Object.assign({},this.state)代码>只是一个浅拷贝stateCopy.media.photos[this.state.media.selectedMediaIndex]
和this.state.media.photos[this.state.media.selectedMediaIndex]
引用了同一个对象,因此我认为您不会从中获得任何好处。如果要创建深度副本,需要使用另一个答案中所示的不可变帮助程序。识别模式并避免重复代码。例如,无需反复访问stateCopy.media.photos[this.state.media.selectedMediaIndex]
。只需将值赋给变量并使用该变量即可
下面是一个较短的实现:
// assuming `e` is either "preview", "featured" or "none"
const photo = stateCopy.media.photos[this.state.media.selectedMediaIndex];
['preview', 'featured', 'none'].forEach(
property => photo.display[property] = property === e
);
或者没有循环:
// assuming `e` is either "preview", "featured" or "none"
Object.assign(
stateCopy.media.photos[this.state.media.selectedMediaIndex],
{
preview: e === 'preview',
featured: e === 'featured',
none: e === 'none',
}
);
还要注意,var stateCopy=Object.assign({},this.state)代码>只是一个浅拷贝stateCopy.media.photos[this.state.media.selectedMediaIndex]
和this.state.media.photos[this.state.media.selectedMediaIndex]
引用了同一个对象,因此我认为您不会从中获得任何好处。如果要创建深度副本,需要使用另一个答案所示的不可变帮助程序
。我使用不可变帮助程序
包,而不是下划线.js
。我不知道使用它的优点或缺点,但结果是这样的
import update from 'immutability-helper';
......
this.state = {
media : {
video : "",
photos : [{
title : "Storefront",
url : "https://cdn.filepicker.io/api/file/cHyLd9KtSNibpsGlQsny",
category : {
interior : false,
exterior : true,
closeup : false
},
display : {
preview : false,
featured : true,
none : false
},
size : "800 x 600",
attribution_link : "",
attribution_text : "",
description : ""
},
{
...
}]
}
}
update(this.state, {
media: {
photos: {
0: {
display: {
preview: {
$set: (e === 'preview') ? true : false
}
featured: {
$set: (e === 'featured') ? true : false
}
none: {
$set: (e === 'none') ? true : false
}
}
}
}
}
})
我使用了immutability helper
包,而不是下划线.js
。我不知道使用它的优点或缺点,但结果是这样的
import update from 'immutability-helper';
......
this.state = {
media : {
video : "",
photos : [{
title : "Storefront",
url : "https://cdn.filepicker.io/api/file/cHyLd9KtSNibpsGlQsny",
category : {
interior : false,
exterior : true,
closeup : false
},
display : {
preview : false,
featured : true,
none : false
},
size : "800 x 600",
attribution_link : "",
attribution_text : "",
description : ""
},
{
...
}]
}
}
update(this.state, {
media: {
photos: {
0: {
display: {
preview: {
$set: (e === 'preview') ? true : false
}
featured: {
$set: (e === 'featured') ? true : false
}
none: {
$set: (e === 'none') ? true : false
}
}
}
}
}
})
这样的方法适用于动态属性(设置外部或内部选项等),如果缺少对象上的某些关键点并且不想添加它们,则可以覆盖:
handleDisplayClick=(e)=>{
让stateCopy=Object.assign({},this.state);
let options=['preview','featured'];
e=(options.indexOf(e)>-1)?e:'none';
Object.key(stateCopy.media.photos[this.state.media.selectedMediaIndex].display).foreach(key=>{
stateCopy.media.photos[this.state.media.selectedMediaIndex]。显示[key]=(key==e);
});
此.setState(状态副本);
}
类似的内容适用于动态属性(设置外部或内部选项等),如果您缺少对象上的某些关键点并且不想添加它们,则可以覆盖:
handleDisplayClick=(e)=>{
让stateCopy=Object.assign({},this.state);
let options=['preview','featured'];
e=(options.indexOf(e)>-1)?e:'none';
Object.key(stateCopy.media.photos[this.state.media.selectedMediaIndex].display).foreach(key=>{
stateCopy.media.photos[this.state.media.selectedMediaIndex]。显示[key]=(key==e);
});
此.setState(状态副本);
}
您可以使用lodash的集合
。请参阅,您可以使用lodash的set
。参考哇。。!!那太有帮助了。谢谢。哇。。!!那太有帮助了。谢谢。谢谢你的解决方案@Shubham。谢谢你的解决方案@Shubham。