我有一个简单/愚蠢的函数,它根据用户与之交互的元素来改变我的状态。我的问题是我为每个组复制了几乎相同的代码。有什么方法可以重构这个吗?
handleRequestDeleteChip = (data, group) => {
// NEED REFACTORING
if (group === "client") {
const updatedSelectedClients = removeItem(this.state.currentJob.selectedClients, data.id);
const updatedJobStatus = {
...this.state.currentJob,
selectedClients: updatedSelectedClients
};
this.setState({currentJob: updatedJobStatus});
} else if (group === "product") {
const updatedSelectedProducts = removeItem(this.state.currentJob.selectedProducts, data.id);
const updatedJobStatus = {
...this.state.currentJob,
selectedProducts: updatedSelectedProducts
};
this.setState({currentJob: updatedJobStatus});
} else if (group === "upload") {
const updatedSelectedUplods = removeItem(this.state.currentJob.selectedUploads, data.id);
const updatedJobStatus = {
...this.state.currentJob,
selectedUploads: updatedSelectedUplods
};
this.setState({currentJob: updatedJobStatus});
}
};
答案 0 :(得分:2)
由于“selected”项与组具有1对1的关系,因此您可以创建Map(或字典对象),根据该组为您提供正确的项目类型。其余的只是使用项目名称:
注意:地图是静态的,因此可以将其移出方法之外。这样就无需在调用方法时重新创建它。
const itemToChange = new Map([['client', 'selectedClients'], ['product', 'selectedProducts'], ['upload', 'selectedUploads']]); // external map of options
handleRequestDeleteChip = (data, group) => {
const selected = itemToChange.get(group); // get the item by group
if(!selected) { // if no selected for the group
// handle by returning, throwing error, fallback, etc...
}
const updatedSelected = removeItem(this.state.currentJob[selected], data.id); // use brackets notation to get the item
this.setState({
...this.state.currentJob,
[selected]: updatedSelected // use computerd properties to set the correct type
});
};
答案 1 :(得分:0)
当然 - 您可以使用["field"]
而非.field
来访问字段的功能..这样的事情(未经测试):
static deleteById(state, key, id) {
const original = state[key];
const updated = removeItem(original, id);
state[key] = updated;
}
handleRequestDeleteChip = (data, group) => {
const updatedJobStatus = {
...this.state.currentJob
};
if (group === "client") {
this.deleteById(updatedJobStatus, "selectedClients", data.id);
} else if (group === "product") {
this.deleteById(updatedJobStatus, "selectedProducts", data.id);
} else if (group === "upload") {
this.deleteById(updatedJobStatus, "selectedUploads", data.id);
}
this.setState({currentJob: updatedJobStatus});
};
如果您可以选择更改group
值以匹配字段名称,那么它可能更容易:
static deleteById(state, key, id) {
const original = state[key];
const updated = removeItem(original, id);
state[key] = updated;
}
handleRequestDeleteChip = (data, group) => {
const updatedJobStatus = {
...this.state.currentJob
};
this.deleteById(updatedJobStatus, group, data.id);
this.setState({currentJob: updatedJobStatus});
};
答案 2 :(得分:0)
允许它可以测试。
handleRequestDeleteChip = (data, group) => {
let updatedJobStatus = { ...this.state.currentJob };
removeCurrentJobItem(updatedJobStatus,group, data.id);
this.setState({currentJob: updatedJobStatus});
};
removeCurrentJobItem = (updatedJobStatus, group, id) => {
if (group === "client") {
const updatedItem = removeItem(updatedJobStatus.selectedClients, id);
updatedJobStatus.selectedClients = updatedItem;
}
if (group === "product") {
const updatedItem = removeItem(updatedJobStatus.selectedProducts, id);
updatedJobStatus.selectedProducts = updatedItem;
}
if (group === "upload") {
const updatedItem = removeItem(updatedJobStatus.selectedUploads, id);
updatedJobStatus.selectedUploads = updatedItem;
}
}
注意:我也会使这个不可变并从“removecurrentJobItem”函数返回一个新实例。这允许纯代码没有副作用。
您还可以测试此方法,而无需担心状态或事件。