React에서 사용할 때 유효하지 않은 날짜 (2 월 31 일 등)를 표시하지 않는 방법

소개



React에서 <input type="date" /> 를 사용하여 날짜를 선택하는 폼을 만들 때 2月31日 라는 무효한 날짜도 선택할 수 있어 버리는 것을 막고 싶었기 때문에 구현해 보았습니다.

input 태그라면 짜증나지 않기 때문에, material-ui의 TextField 컴퍼넌트를 사용하고 있습니다만, 기능 자체는 같습니다.

날짜 선택 만들기


date 로 날짜 상태를 관리합니다.valuedate 를 전달해, onChange 이벤트를 받고 상태를 갱신하는 보통의 처리입니다.

App.js
export default function App() {
  const [date, setDate] = useState("");

  return (
    <div className="App">
      <FormControl variant="outlined">
        <TextField
          variant="outlined"
          type="date"
          value={date}
          onChange={e => onChangeDate(e}
        />
      </FormControl>
    </div>
  );
}

우선 onChangeDate 는 그대로 상태를 갱신해 본다.

App.js
const onChangeDate = (e) => {
  setDate(e.target.value);
}

↑키등으로 선택하면, 이런 식으로 무효인 일자를 선택할 수 있어 버리는군요・・・


onChangeDate로 좋은 느낌으로 조정



문제점으로는
  • 2월은 윤년이 있기 때문에, 28or29일
  • 4/6/9/11월은 30일까지

  • 그래서, 1개전의 상태 date 를 참조해, 재기록해 갑니다.

    유효하지 않은 날짜일 때 e.target.value 에는 값이 포함되어 있지 않으므로 값이 들어있을 때는 그대로 상태를 업데이트합니다.

    그 이외의 경우는 월마다 분기해 써 갑니다.

    App.js
    const onChangeDate = (e) => {
    
      if (e.target.value) {
        setDate(e.target.value);
      } else {
        const nowYear = date.slice(0, 4);
        const nowMonth = date.substr(5, 2);
        const nowDate = date.slice(-2);
    
        if (nowDate !== "01") {
          setDate(`${nowYear}-${nowMonth}-01`);
        }
        else{
          switch (nowMonth) {
            case "02":
              if ((nowYear * 1) % 4 === 0) {
                setDate(`${nowYear}-${nowMonth}-29`);
              } else {
                setDate(`${nowYear}-${nowMonth}-28`);
              }
              break;
            case "04":
            case "06":
            case "09":
            case "11":
              setDate(`${nowYear}-${nowMonth}-30`);
              break;
            default:
              break;
          }
        }
      }
    }
    

    이제 무효한 날짜가 우선 들어가지 않게 되었습니다! !

    다만, 이것이라면 3/31 로부터 달을 2월로 변경(↓ 화살표)하면, 3/1 에 1회가 되어 버립니다.

    조금 기분 나쁘네요. . .

    그러나, e.target.value 에 값이 들어오지 않고, 연월일의 어느 값을 변경했을지도 모르기 때문에,
    어쩔 수 없어요.

    세상에 나돌고 있는 캘린더 앱이라든지의 일자는, 보통으로 2/31일이라든지 선택할 수 있게 되어 있어, 보존할 수 없게 하고 있거나 하기 때문에 이것이 베스트 프랙티스일까요.

    요약



    이번에는 날짜 선택의 잘못된 날짜를 표시하지 않도록 시도했습니다.

    아직 기분 나쁘기 때문에 베스트 프랙티스를 아시는 분은 코멘트를 부탁합니다! !

    좋은 웹페이지 즐겨찾기