Javascript 使用占位符信息正确构造数组,直到用选定对象填充为止

Javascript 使用占位符信息正确构造数组,直到用选定对象填充为止,javascript,reactjs,Javascript,Reactjs,这是一个令人困惑的问题,我不知道如何正确地用谷歌搜索它,所以如果它已经被回答了,我道歉。我正在尝试创建一个build your own product类型的应用程序,允许用户选择成品的每一部分,我不确定应该如何构造数据以正确存储用户选择。现在我有一个如下结构的数组: selectedParts: [ { component: "color", selected: null, }, { component: "wheels",

这是一个令人困惑的问题,我不知道如何正确地用谷歌搜索它,所以如果它已经被回答了,我道歉。我正在尝试创建一个build your own product类型的应用程序,允许用户选择成品的每一部分,我不确定应该如何构造数据以正确存储用户选择。现在我有一个如下结构的数组:

selectedParts: [
    {
      component: "color",
      selected: null,
    },
    {
      component: "wheels",
      selected: null,
    },
    {
      component: "size",
      selected: null,
    },
    (...etc.)
  ],
当他们选择他们的选择时,它会用零件对象填充相应对象的“选定”字段。下面是我运行以填充该数组的函数(我正在使用React,该数组处于我的状态):

通过查找他们当前从中选择的类别的索引,然后克隆阵列,并使用索引将部件添加到克隆阵列中,然后将新阵列推送到状态,从而将部件放入阵列中


我觉得这是不对的,而且比应该的更复杂。我想尝试将其全部保存在一个数组中,以便在最后映射并轻松打印出完整的订单摘要,但如果这是一种错误的方法,那么推荐的方法是什么?将对象嵌套在“Order”对象中比使用数组更好吗?

如果您可以选择使用哪种数据结构,那么将
selectedParts
作为一个对象对您来说更容易,性能也更好,因为您可以在固定时间内访问对象(不必每次都循环). 属性将是
组件
,值将是
部分
对象:

selectedParts: {
  color: null,
  wheels: null,
  size: null,
  ...
}
然后要更新它,您仍然需要复制和更新,但要简单得多:

const onSelectPart = part => {
  const selectedParts = {...this.state.selectedParts}; 
  selectedParts[this.state.partCategory] = part; // using "computed names"
  this.setState({ selectedParts });
}
最后,您可以在
selectedParts
条目上打印订单循环:

const printOrderSummary = selectedParts => {
  // Note: [category, part] is just key, value of your object
  for (let [category, part] of Object.entries(selectedParts)) {
    if (part === null) part = 'Not selected'; // or skip the category, etc.

    // this would be whatever you're currently doing to map your order
    console.log(`${category}: ${part}`);
  }
}

我做的有点不同,请让我知道这是否也是一种很好的方法:)。我照你说的做了,将selectedParts切换到一个对象,然后我就反对了。使用partCategory查找密钥,将新零件分配到selectedParts对象中。因此,代码如下所示:addToOrder=part=>{let{partCategory}=this.state let order=this.state.order Object.assign(order[partCategory],part)}(this.state.order是selectedParts我刚刚切换了名称)@BenCavenagh我必须检查一下!我不会太详细,但简短的回答是,我不推荐。通常您会遇到错误(有时是无声的),除非订单[partCategory]已经是一个对象,而part是一个对象
order={…this.state.order}
order=Object.assign({},this.state.order
)相同。不要这样做(我会在后面解释原因),但仅供参考,如果你想这样分配,最好是
Object.assign(order,{[partCategory]:part}
。之所以不这样做,是因为您.resact批处理setState调用以提高性能,这样可能会降低性能,如果您将状态作为道具传递给另一个组件,该组件在更改后可能不会重新渲染。这就是为什么最好复制并使用
setState()
更新。最后,我想补充一点,如果您确实想将其保留为一个数组,您可以在一行中查找索引、更新和设置状态,但可读性要差得多,而且您基本上是在做同样的事情,需要另一个循环(如果您有很多项,则速度可能会慢):
this.setState(prevState=>({selectedParts:prevState.selectedParts.map(item=>item.component===prevState.partCategory?{…item,selected:part}:item)}));
如果有什么不清楚的地方或者需要更多关于其中一件事情的解释,请告诉我。听起来像是一个很酷的应用程序!
const printOrderSummary = selectedParts => {
  // Note: [category, part] is just key, value of your object
  for (let [category, part] of Object.entries(selectedParts)) {
    if (part === null) part = 'Not selected'; // or skip the category, etc.

    // this would be whatever you're currently doing to map your order
    console.log(`${category}: ${part}`);
  }
}