使用ReactJS在工作日提供多个时隙 [英] Multiple time slots for Week days using ReactJS

查看:37
本文介绍了使用ReactJS在工作日提供多个时隙的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果有人可以帮助我优化以下代码。我正在尝试创建一个注册页面,用户可以在其中选择所选日期的时间。用户可以选择在同一天选择多行。.codeandbox的链接为


If anyone can help me to optimize the following code. I am trying to create a registration page where users can select their time availability for selected days. Users have option to select multiple rows for the same day.. The link for codesandbox is https://codesandbox.io/s/react-hook-helper-availability-0r6bd?file=/src/Second.js. Though i have achieved this but it can be further be optimized as i am using the same code for different days. I am reusing the same code. I have added for just Monday and Tuesday, in case i have to use Monday to Saturday, then i will have to repeat the same codes with changes in few fields.

  const [monday, setMonday] = useState([{ FROM: "", TO: "" }]);
  const [tuesday, setTuesday] = useState([{ FROM: "", TO: "" }]);

  const [time, setTime] = useState([
    { Id: "00:30", value: "00:30" },
    { Id: "01:00", value: "01:00" },
    { Id: "01:30", value: "01:30" },
    { Id: "02:00", value: "02:00" },
......
let timeList =
    time.length > 0 &&
    time.map((item, i) => {
      return (
        <>
          <option key={item.Id} value={item.id}>
            {item.value}
          </option>
        </>
      );
    }, this);


On add, remove actions

const handleInputChangeForMonday = (e, index) => {
    const { name, value } = e.target;
    const list = [...monday];
    list[index][name] = value;
    setMonday(list);
  };

  // handle click event of the Remove button
  const handleRemoveClickForMonday = (index) => {
    const list = [...monday];
    list.splice(index, 1);
    setMonday(list);
  };

  // handle click event of the Add button
  const handleAddClickForMonday = () => {
    setMonday([...monday, { FROM: "", TO: "" }]);
  };

  // handle input change
  const handleInputChangeForTuesday = (e, index) => {
    const { name, value } = e.target;
    const list = [...tuesday];
    list[index][name] = value;
    setTuesday(list);
  };

  // handle click event of the Remove button
  const handleRemoveClickForTuesday = (index) => {
    const list = [...tuesday];
    list.splice(index, 1);
    setTuesday(list);
  };

  // handle click event of the Add button
  const handleAddClickForTuesday = () => {
    setTuesday([...tuesday, { FROM: "", TO: "" }]);
  };

Now this is the repeated code.

<form onSubmit={onSubmit}>
        {monday.map((x, i) => {
          return (
            <React.Fragment>
              <select
                name="FROM"
                value={x.FROM}
                onChange={(e) => handleInputChangeForMonday(e, i)}
              >
                <option selected hidden>
                  From
                </option>
                {timeList}
              </select>
              &nbsp;&nbsp;&nbsp;
              <select
                name="TO"
                value={x.TO}
                onChange={(e) => handleInputChangeForMonday(e, i)}
                placeholder="select your Institute"
              >
                <option selected hidden>
                  TO
                </option>
                {timeList}
              </select>
              <div style={{ textAlign: "left", width: "84%" }}>
                {monday.length !== 1 && (
                  <label
                    as="a"
                    onClick={() => handleRemoveClickForMonday(i)}
                    style={{ marginRight: "10px" }}
                  >
                    remove
                  </label>
                )}

                {monday.length - 1 === i && (
                  <button
                    type="button"
                    as="a"
                    onClick={handleAddClickForMonday}
                    style={{ marginRight: "10px" }}
                  >
                    add
                  </button>
                )}
              </div>
            </React.Fragment>
          );
        })}
        <br />
        <br />

        {tuesday.map((x, i) => {
          return (
            <React.Fragment>
              &nbsp;&nbsp;&nbsp;
              <select
                name="FROM"
                value={x.FROM}
                onChange={(e) => handleInputChangeForTuesday(e, i)}
              >
                <option selected hidden>
                  From
                </option>
                {timeList}
              </select>
              &nbsp;&nbsp;&nbsp;
              <select
                name="TO"
                value={x.TO}
                onChange={(e) => handleInputChangeForTuesday(e, i)}
                placeholder="select your Institute"
              >
                <option selected hidden>
                  TO
                </option>
                {timeList}
              </select>
              <div style={{ textAlign: "left", width: "84%" }}>
                {tuesday.length !== 1 && (
                  <label
                    as="a"
                    onClick={() => handleRemoveClickForTuesday(i)}
                    style={{ marginRight: "10px" }}
                  >
                    remove
                  </label>
                )}

                {tuesday.length - 1 === i && (
                  <button
                    type="button"
                    as="a"
                    onClick={handleAddClickForTuesday}
                    style={{ marginRight: "10px" }}
                  >
                    add
                  </button>
                )}

解决方案

To reduce redundancy you can look at what code is repeated and think of it more abstractly.

For example, the following code abstractly copies the entries for a day, removes an element, and updates state with new array for that day

// handle click event of the Remove button
const handleRemoveClickForMonday = (index) => {
  const list = [...monday];
  list.splice(index, 1);
  setMonday(list);
};

Now that you can abstractly operate on any day, think of a data structure that lends itself to looking up a specific day to operate on, like a map. In javascript it is common to use an object ({}) as a map of key-value pairs.

Convert state to object with day keys

const [days, setDays] = useState({
  monday: [{ FROM: "", TO: "" }],
  tuesday: [{ FROM: "", TO: "" }],
  wednesday: [{ FROM: "", TO: "" }],
  thursday: [{ FROM: "", TO: "" }],
  friday: [{ FROM: "", TO: "" }],
  saturday: [{ FROM: "", TO: "" }],
  sunday: [{ FROM: "", TO: "" }],
});

Update mounting effect hook (probably room for improvement here as well since just initializing data really; I didn't dig in on what the AVAILABILITY_XXX's were)

useEffect(() => {
  if (AVAILABILITY_MONDAY.length > 0)
    setDays((days) => ({
      ...days,
      monday: AVAILABILITY_MONDAY
    }));

  if (AVAILABILITY_TUESDAY.length > 0)
    setDays((days) => ({
      ...days,
      tuesday: AVAILABILITY_TUESDAY
    }));

  // etc for each day of the week
}, []);

Convert submit handler to access new state shape

const onSubmit = (data) => {
  const e = {
    target: {
      name: "AVAILABILITY_MONDAY",
      value: days.monday
    }
  };
  const f = {
    target: {
      name: "AVAILABILITY_TUESDAY",
      value: days.tuesday
    }
  };
  // etc for each day

  setForm(e);
  setForm(f);
  // etc

  navigation.next();
};

Convert handlers to take a day key

// handle input change
const handleInputChangeForDay = (e, day, index) => {
  const { name, value } = e.target;
  const list = [...days[day]];
  list[index][name] = value;
  
  setDays((days) => ({
    ...days,
    [day]: list
  }));
};

// handle click event of the Remove button
const handleRemoveClickForDay = (day, index) => {
  const list = [...days[day]];
  list.splice(index, 1);
  
  setDays((days) => ({
    ...days,
    [day]: list
  }));
};

// handle click event of the Add button
const handleAddClickForDay = (day) => () => {
  
  setDays((days) => ({
    ...days,
    [day]: [...days[day], { FROM: "", TO: "" }]
  }));
};

Create an array of key-value pairs from state and map each day

{Object.entries(days).map(([dayKey, day]) => {
  return day.map((x, i) => {
    return (
      <React.Fragment>
        Day: {dayKey}
        <select
          name="FROM"
          value={x.FROM}
          onChange={(e) => handleInputChangeForDay(e, dayKey, i)}
        >
          <option selected hidden>
            From
          </option>
          {timeList}
        </select>
        &nbsp;&nbsp;&nbsp;
        <select
          name="TO"
          value={x.TO}
          onChange={(e) => handleInputChangeForDay(e, dayKey, i)}
          placeholder="select your Institute"
        >
          <option selected hidden>
            TO
          </option>
          {timeList}
        </select>
        <div style={{ textAlign: "left", width: "84%" }}>
          {day.length !== 1 && (
            <label
              as="a"
              onClick={() => handleRemoveClickForDay(dayKey, i)}
              style={{ marginRight: "10px" }}
            >
              remove
            </label>
          )}

          {day.length - 1 === i && (
            <button
              type="button"
              as="a"
              onClick={handleAddClickForDay(dayKey)}
              style={{ marginRight: "10px" }}
            >
              add
            </button>
          )}
        </div>
      </React.Fragment>
    );
  });
})}

这篇关于使用ReactJS在工作日提供多个时隙的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆