使用键简化对象的设置值
Simplify setting values of object using key
有什么办法可以简化下面的代码吗?可能是通过使用下划线 js,我浏览了文档,但找不到任何可以帮助我解决动态键值对问题的东西。
对象:
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);
if(e == "preview"){
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;
}
else if(e == "featured"){
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;
}
else{
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;
}
this.setState(stateCopy);
}
识别模式并避免重复代码。例如。无需一遍又一遍地访问 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]
指的是同一个对象,所以我认为您不会从中获得任何好处。如果你想创建一个深拷贝,你需要使用 immutable-helper
如另一个答案所示。
我使用 immutability-helper
包而不是 underscore.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) => {
let stateCopy = Object.assign({}, this.state);
let options = ['preview', 'featured'];
e = (options.indexOf(e) > -1) ? e : 'none';
Object.keys(stateCopy.media.photos[this.state.media.selectedMediaIndex].display).foreach(key => {
stateCopy.media.photos[this.state.media.selectedMediaIndex].display[key] = (key === e);
});
this.setState(stateCopy);
}
有什么办法可以简化下面的代码吗?可能是通过使用下划线 js,我浏览了文档,但找不到任何可以帮助我解决动态键值对问题的东西。
对象:
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);
if(e == "preview"){
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;
}
else if(e == "featured"){
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;
}
else{
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;
}
this.setState(stateCopy);
}
识别模式并避免重复代码。例如。无需一遍又一遍地访问 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]
指的是同一个对象,所以我认为您不会从中获得任何好处。如果你想创建一个深拷贝,你需要使用 immutable-helper
如另一个答案所示。
我使用 immutability-helper
包而不是 underscore.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) => {
let stateCopy = Object.assign({}, this.state);
let options = ['preview', 'featured'];
e = (options.indexOf(e) > -1) ? e : 'none';
Object.keys(stateCopy.media.photos[this.state.media.selectedMediaIndex].display).foreach(key => {
stateCopy.media.photos[this.state.media.selectedMediaIndex].display[key] = (key === e);
});
this.setState(stateCopy);
}