React中的条件对象名称

时间:2017-11-08 11:02:32

标签: reactjs ecmascript-6 refactoring

我有一个简单/愚蠢的函数,它根据用户与之交互的元素来改变我的状态。我的问题是我为每个组复制了几乎相同的代码。有什么方法可以重构这个吗?

  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});
    }
  };

3 个答案:

答案 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”函数返回一个新实例。这允许纯代码没有副作用。

您还可以测试此方法,而无需担心状态或事件。