我有一个通过api调用呈现的数据表。它显示来自初始对象的4个值。我主要关心name
的值,因为这是post请求后面的重要内容。
表中的每一行都有一个复选框。选中复选框(true
)后,与该复选框关联的名称将作为对象添加到名为selectedFields
的对象中。例如,如果我选中名为id
的复选框,它会创建一个对象存储,如下所示:
"selectedFields": {
"id" : {}
}
这工作得很好。但是,我已经添加了3个与每个name
相关联的输入框。输入是lengthType
、size
、maxArrayElements
,当然都是用户可选的。我遇到的问题是将这些值添加回对象,使其看起来如下所示:
"selectedFields": {
"id": {
lengthType: Variable,
size: 1,
maxArrayElements: 1
},
"price": {
lengthType: Fixed,
size: 10,
maxArrayElements: 1
}
}
如何将这3个值重新添加到创建的name
对象中,使其看起来像上面的示例?
我不想发布一大堆代码,所以我发布了checkbox函数,该函数使用适当的选定names
创建selectedFields
对象。我怀疑输入值应该以某种方式添加到这里,但我不确定。
checkbox = ({ name, isChecked }) => {
//handle check box of each fieldName
const obj = this.state.fieldNames.find(field => field.name === name);
if (isChecked === true) {
//checked conditional
this.setState(
{
selectedFields: {
...this.state.selectedFields,
[name]: {
...obj
}
}
},
() => {
console.log(
"callback in isChecked if conditional",
this.state.selectedFields
);
}
);
} else {
const newSelectedFields = this.state.selectedFields;
delete newSelectedFields[name];
this.setState(
{
selectedFields: newSelectedFields
},
() => {
console.log(
`box unchecked, deleted from object --->`,
this.state.selectedFields
);
}
);
}
};
您必须进行第一个下拉选择才能查看数据。
发布于 2019-05-31 06:53:19
回答
您需要更改一些内容,因为没有说明在根状态对象之外将新状态分配到何处。
Index.js中的处理程序
change事件的处理程序不会通过查找对象的名称来确定它是否存在。如果你想把它添加到指定的子对象中,你最好确保它在那里。
我们调整处理程序以获取一个对象名,并在该特定对象上使用object.assign
进行setState (如果存在):
注意:由于lengthType
没有name
属性,我们只需为其提供一个字符串。e.currentTarget
将提供选项跨度,而不是根Dropdown
元素,因此即使向该组件提供name
属性也不允许我们使用e.currentTarget.name
-如果您想要不同的东西,可能需要咨询Semantic UI documentation。我给了它一个快速扫描,但不想深入它。
handleChange = (e, obj_name) => {
if (this.state.selectedFields[obj_name]) {
let selectedFields = Object.assign({}, this.state.selectedFields);
selectedFields[obj_name] = Object.assign(
this.state.selectedFields[obj_name],
{ [e.target.name]: e.target.value }
);
this.setState({ selectedFields });
}
};
onLengthTypeChange = (e, obj_name) => {
if (this.state.selectedFields[obj_name]) {
let selectedFields = Object.assign({}, this.state.selectedFields);
selectedFields[obj_name] = Object.assign(
this.state.selectedFields[obj_name],
{ lengthType: e.currentTarget.textContent }
);
this.setState({ selectedFields });
}
};
当然,如果您不调整组件上的onChange
事件,以便除了事件对象之外,它们还发送您的对象名称,则上述方法将不起作用。
组件文件中的处理程序
注意:这很奇怪,因为在您的Index.js
文件中,您似乎使用lengthType
完成了一半的操作,但是您并没有传递额外的数据。您不能简单地将参数传递到处理程序中-要使其工作,您需要将一个匿名函数传递给onChange
属性,该属性将接受事件并将其传递给处理程序函数,并使用作为对象名:
<Table.Cell>
<Dropdown
placeholder="Pick a length Type:"
clearable
selection
search
fluid
noResultsMessage="Please search again"
label="lengthType"
multiple={false}
options={lengthTypeOptions}
header="Choose a Length Type"
onChange={e => onLengthTypeChange(e, name)}
value={lengthType}
required
/>
</Table.Cell>
<Table.Cell>
<Input
onChange={e => handleChange(e, name)}
value={this.state.size}
type="number"
name="size"
min="1"
placeholder="1"
required
/>
</Table.Cell>
<Table.Cell>
<Input
onChange={e => handleChange(e, name)}
value={this.state.maxArrayElements}
type="number"
name="maxArrayElements"
placeholder="1"
min="1"
max="100"
required
/>
</Table.Cell>
一旦调整了这些内容,在相应的复选框为selected之后,代码将更新子对象上指定的属性。
最后注意事项:
我没有调整它来保存之前的状态,如果您取消选中,然后选中框。你的问题中没有具体说明,我不想做假设。
代码沙盒:
调整后的代码沙箱:https://codesandbox.io/s/createqueryschema-table-rewrite-bwvo4?fontsize=14
其他建议:
selectedFields
被声明为Array
,然后当选中任何复选框时,它会立即转换为Object
。我建议不要这么做。在运行应用程序的过程中更改属性上的数据类型非常需要trouble.Index.js
文件中提供一个checkbox
函数。在您的组件中,这被简单地称为box
。我建议在从父级传递到子级时,保持属性和状态的名称相同。如果其他人不得不进来维护它,这要容易得多-更不用说更容易保持你自己的理智了。checkbox
函数从孩子那里获取道具,并将它们传递给父母。这将是将收集的数据传递到父级上的缓存、本地/会话存储或您想要对数据执行的任何操作的地方。相反,你可以编写这样的代码:如果在调用输入处理程序时选中了复选框,则执行保存-但我想说的是,在render
上可能是最好的,因为屏幕无论如何都在不断更新,而且你现在有checkbox
函数可以随时传递道具。这是你的偏好,所以这是你的call祝好运!希望这能有所帮助!
https://stackoverflow.com/questions/56385991
复制相似问题