조회기간 설정

ssongyi·2023년 2월 24일
0

조폐공사 Project

목록 보기
3/6

뭐부터 써야할지 모르겠으니 기능을 차근차근 적어봐야겠다..
내가 처음에 구현한 것은 조회기간 설정 부분이다.
전부 내가 한 것은 아니고, 팀장님께서 많이 도와주셨다.
그래서 복습 겸 코드 분석 겸 정리해보고자 한다.


기본 날짜 전달 기준 처리

우선 앞 부분의 날짜를 기본 날짜의 전 달 기준으로 처리해야했다.
여기서 moment()를 처음으로 써 봤다.

  // 기본 날짜 전달 기준 처리
  let defaultDate = new Date(moment().format('YYYY-MM'));
  const diff = moment(defaultDate).format('DD');

  if (Number(diff) < 10) {
    defaultDate = new Date(moment().subtract(1, 'months').format('YYYY-MM'));
  }
  1. defaultDate 라는 변수를 만든다.
    1-1. moment()를 사용한 새로운 객체를 만든다.
    1-2. format('YYYY-MM') = '2023-01' 형식으로 나타낸다.

  2. test 라는 변수를 만든다.
    --> 기획서 상에서, 당월 기준 10일 이전이면 전달로 처리하고
    10일 이후라면 당월로 처리해야하라고 적혀있기 때문에 만듦

  3. defaultData의 DD (test) 가 10보다 작으면
    3-1. 새로운 defaultData를 만듦
    3-2. subtract(1, months) = 기준 일자 1달 전


FormDate 만들기

  1. 타입스크립트여서 자료형을 선언해줘야한다.

  2. FormDateLayout 라는 component를 만들어서 styled-components로 스타일을 만들어준다.

import * as React from 'react';
import styled from 'styled-components';
import moment from 'moment';

export interface IFormDate {
  value?: any;
  type?: string;
  defaultValue?: string;
  className?: string;
  name?: string;
  id?: string;
  min?: string;
  max?: string;
  onChange: (e) => void;
}

const FormDateLayout = styled.div`
  .input_date {
    background-image: url('/img/calendar_12cm_icon.png');
    background-size: 14px;

    font-size: 14px;
    font-weight: 400;

    letter-spacing: 0em;
    text-align: left;
  }

  .cm_input_date {
    width: 100%;
    max-width: 138px;
    height: 40px;
    padding: 11px;
    border: 1px solid #dbdbdb;
    border-radius: 3px;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-repeat: no-repeat;
    background-position-x: 93%;
    background-position-y: 50%;
    background-color: #ffffff;
    cursor: pointer;
    /* background-image: url(/img/icon-calendar.png); */
    position: relative;
  }

  .cm_input_date::-webkit-calendar-picker-indicator {
    background: transparent;
    z-index: 1;
    width: 100%;
    height: 100%;
    position: absolute;
    cursor: pointer;
  }
`;

const FormDate: React.FC<IFormDate> = ({
  value,
  className,
  name,
  id,
  type,
  defaultValue,
  min,
  max,
  ...props //이거 넣어야 이벤트 되넹 ㅎㅎ
}: IFormDate) => {
  return (
    <FormDateLayout>
      <input
        value={value ? moment(value).format('YYYY-MM') : defaultValue}
        type={type ? type : 'date'}
        name={name}
        id={id}
        defaultValue={defaultValue}
        className={`input_date cm_input_date hp_mr-30 ${className}`}
        min={min}
        max={max}
        {...props}
      />
    </FormDateLayout>
  );
};

export default FormDate;

void ?

IFormDate 내부의 onChange: (e) => void;

  • 추상화(abstract) 개념
  • 당장은 어떻게 사용될 지 모르나 해당 인터페이스를 가지고 필요에 따라 바꿔 쓰기 위해 void로 선언


3. 그리고 향후 활용할 FormDate를 만든다.


여기서 React.FC 란 ?

  • React 컴포넌트는 옵션으로 propsTypes, displayName, defaultProps, contestTypes 를 props로 내려줄 수 있지만,
    TypeScript에서는 이게 리액트에서 만들었다는 것을 알 수 없다.
    • 그래서 React.FC<>를 명시함으로써
      해당 함수가 리액트의 컴포넌트라는 것을 알려 줄 수 있다.
    • 이로써 propsTypes, displayName, defaultProps, contextTypes 등도 배정 받을 수 있다.
    • React.FC<프롭타입> 제네릭에 프롭타입을 적어서 props의 타입도 정의할 수 있다.
    • children 전달 시에도 React.FC는 자동적으로 전달을 해주는 반면, 일반 함수형 컴포넌트는 interface 등에 수동적으로 타입을 명시해야 한다.

React에서 Typescript 사용하기

< 단점 >

  • children을 암시적으로 가지고 있다.
  • 제네릭을 지원하지 않는다.
  • 네임 스페이스 패턴을 이용할 때 더 불편하다.
  • FC를 이용하면 코드가 더 길어진다

라는 단점으로 인해 React 18 이상부터 없어졌다!
하지만 우리는 활용했다...ㅋㅋ
보통 단점을 인지하고 있으면서도 활용하는 이유는, 편하고 익숙하기 때문이라고 한다.

리액트에서 FC를 사용하지 말아야 하는 이유


부모 컴포넌트에서 자식 컴포넌트에 props 전달 시, 자식이 받게 될 props interface(IFormDate)를 정의해야 한다!

  1. 위에 타입을 선언해뒀던 interface IFormDate를 props로 가져왔다

...props ?

명확하게 이해는 못했지만,
특정 태그에서 기본적으로 사용 가능한 값들을 의미하는 것이 아닐까?

{...props}를 첨부하지 않으면
onClick/onChange => (e) => 에서
내가 선언한 onChange 이용이 불가했다.

{...props}라는 속성을 첨부하니, 이벤트가 정상적으로 작동했다.


FormDate 활용

params는 백엔드에서 요청한 request 값들이다.

만들어둔 defaultData를 활용해 FormDate에 적용한다.

        <FormDate
                type="month"
                id="startDateId"
                value={params.strtDt}
                max={moment(defaultDate).format('YYYY-MM')}
                onChange={(e) => {
                  setParams({ ...params, strtDt: moment(e.target.value).format('YYYYMM') });
                }}
              />

              <span className="hp_mr-15 hp_ml-15 un_wave">{' ~ '}</span>

              <FormDate
                type="month"
                id="endDateId"
                value={params.endDt}
                min={params.strtDt}
                max={moment(defaultDate).format('YYYY-MM')}
                onChange={(e) => {
                  setParams({ ...params, endDt: moment(e.target.value).format('YYYYMM') });
                }}
              />

onClick에 setter를 넣으며 마무리!

0개의 댓글