Javascript 使用键简化对象的设置值

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

有没有办法简化以下代码?可能是通过使用下划线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);
如果(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。