结合这 2 个 javascript 函数的最佳方式

Best way to combine these 2 javascript functions

我正在尝试以一种优雅的方式组合这两个功能。我已经通过使用 switch 语句和 const 变量来重复值

来降低复杂性

此函数按给定的日、周或 2 周减去日值

const handleLeft = (
  active: any,
  setActiveDate: any,
  setParagonActiveDate: any
) => {
  const time = (prevDay: any, length: number) =>
    moment(prevDay)
      .subtract(length, 'd')
      .format('YYYY/MM/DD');
  switch (active) {
    case 'day':
      setActiveDate((prevDay: any) => time(prevDay, 1));
      setParagonActiveDate &&
        setParagonActiveDate((prevDay: any) => time(prevDay, 1));
      break;
    case 'week':
      setActiveDate((prevDay: any) => time(prevDay, 6));
      setParagonActiveDate &&
        setParagonActiveDate((prevDay: any) => time(prevDay, 6));
      break;
    case '2weeks':
      setActiveDate((prevDay: any) => time(prevDay, 13));
      setParagonActiveDate &&
        setParagonActiveDate((prevDay: any) => time(prevDay, 13));
  }
};

此函数按给定的日、周或 2 周添加日期值

const handleRight = (
  active: any,
  setActiveDate: any,
  setParagonActiveDate?: any
) => {
  const time = (prevDay: any, length: number) =>
    moment(prevDay)
      .add(length, 'd')
      .format('YYYY/MM/DD');
  switch (active) {
    case 'day':
      setActiveDate((prevDay: any) => time(prevDay, 1));
      setParagonActiveDate &&
        setParagonActiveDate((prevDay: any) => time(prevDay, 1));
      break;
    case 'week':
      setActiveDate((prevDay: any) => time(prevDay, 6));
      setParagonActiveDate &&
        setParagonActiveDate((prevDay: any) => time(prevDay, 6));
      break;
    case '2weeks':
      setActiveDate((prevDay: any) => time(prevDay, 13));
      setParagonActiveDate &&
        setParagonActiveDate((prevDay: any) => time(prevDay, 13));
  }
};

唯一的区别是在 moment 之后执行 .subtract 还是 .add,您可以使用方括号内的条件运算符和第四个参数在单个函数中执行此操作:

const handleLeftOrRight = (
    active: any,
    setActiveDate: any,
    setParagonActiveDate: any,
    add: boolean
  ) => {
    const time = (prevDay: any, length: number) =>
      moment(prevDay)
        [add ? 'add' : 'subtract'](length, 'd')
        .format('YYYY/MM/DD');
    // rest of your code
  };

然后使用,例如

handleLeftOrRight(active, setActiveDate, setParagonActiveDate, true)

而不是

handleRight(active, setActiveDate, setParagonActiveDate)

并且将 false 作为第四个参数而不是 handleLeft.

传递也是如此

但是由于您使用的是 TypeScript,我也强烈建议您正确输入内容,以实际利用 TypeScript 的类型系统 - 在 TypeScript 中,避免 any 几乎总是一个好主意,因为它不是类型安全的 - 它可以分配给任何东西并在任何地方使用,从而打开了与类型相关的运行时错误或错误的可能性。例如,active 可以是 'day''week''2weeks',因此您可以:

const handleLeftOrRight = (
    active: 'day' | 'week' | '2weeks',

而不是使用 any.

另一种改进代码并使事情变得更 DRYer 的方法是让一个对象将 active 值映射到传递给 time.

的第二个参数
const daysByActive = {
    day: 1,
    week: 6,
    '2weeks': 13
}
const handleLeftOrRight = (
    active: 'day' | 'week' | '2weeks',
    setActiveDate: any,
    setParagonActiveDate: any, // this might be improved by changing to boolean?
    add: boolean
) => {
    const time = (prevDay: any, length: number) =>
        moment(prevDay)
            [add ? 'add' : 'subtract'](length, 'd')
            .format('YYYY/MM/DD');
    const days = daysByActive[active];
    setActiveDate((prevDay: any) => time(prevDay, days));
    if (setParagonActiveDate)
        setParagonActiveDate((prevDay: any) => time(prevDay, days));
};

您可以使用 add|subtract 布尔参数,用作动态 属性 以确定使用哪个 moment 对象函数。除此之外,这两个功能之间没有区别。

const handleLeftRight = (
  active: any,
  setActiveDate: any,
  setParagonActiveDate: any,
  add: boolean
) => {
  const time = (prevDay: any, length: number) =>
    moment(prevDay)[add ? 'add' : 'subtract'](length, 'd')
      .format('YYYY/MM/DD');

  switch (active) {
    case 'day':
      setActiveDate((prevDay: any) => time(prevDay, 1));
      setParagonActiveDate &&
        setParagonActiveDate((prevDay: any) => time(prevDay, 1));
      break;
    case 'week':
      setActiveDate((prevDay: any) => time(prevDay, 6));
      setParagonActiveDate &&
        setParagonActiveDate((prevDay: any) => time(prevDay, 6));
      break;
    case '2weeks':
      setActiveDate((prevDay: any) => time(prevDay, 13));
      setParagonActiveDate &&
        setParagonActiveDate((prevDay: any) => time(prevDay, 13));
  }
};