🤹🏻‍♀️ Javascript/🥎 Typescript

체크박스 typescript (useState Type)

ji-hyun 2022. 2. 25. 00:44

체크박스 typescript 참고

useState Type 지정하는 방법 참고하자. (인턴때 헤맸던 부분)

 

 

 

 

 

 

< 제약조건 >

1. DatePicker
기본값: 접속한 날짜를 기준으로 30일간의 데이터를 조회할 수 있도록 설정
- 예외처리
최대 기간: 최대로 조회할 수 있는 날짜의 범위는 1년
날짜 조회: 오늘 이후의 날짜는 조회할 수 없도록 예외처리
시작일과 종료일: 시작일이 종료일을 넘을 수 없도록 예외처리

 

 


 2. 검색 창
글자 제한: 20글자 이상의 검색어를 입력할 수 없도록 예외처리

 

 


 3. 검색 초기화
조회 기간 및 검색어, 필터링(성별, 광고 종류, 비고) 초기화 및 데이터 Reload

 

 


 4. 필터링
기본값: 모든 체크박스들이 체크되도록 기본값 설정
예외처리: 각각의 필터링 조건들에는 최소 하나의 체크 박스가 선택되있어야 한다.

 

 


 5. 테이블
No.: 페이지네이션을 위해 선택된 페이지 값을 기반으로 숫자 노출
Order By: No.를 제외한 나머지 조건들로 정렬 기능 추가
Pagination: 한 페이지 당 10개의 데이터를 노출 및 페이지 변경 시 다음 데이터 로딩

 

 

 

 

 

 

 

상태관리

 

import React, { useState } from "react";
import { SearchBtnList } from "./SearchBtnList/index";
import InputContainer from "./InputContainer";
import { DatePickerCustom } from "components";
import moment from "moment";
import "react-datepicker/dist/react-datepicker.css";
import styled from "styled-components";
import CheckBoxContent from "./CheckBox";

export default function SearchBoard() {
  // 검색관련 state
  const [inputValue, setInputValue] = useState("");

  // 날짜관련 state
  const defaultDate = moment().subtract(1, "month").toDate();
  const [startDate, setStartDate] = useState(defaultDate);
  const [endDate, setEndDate] = useState(new Date());
  const onChangeStart = (date: Date) => setStartDate(date);
  const onChangeEnd = (date: Date) => setEndDate(date);

  // 체크박스관련 state
  const [genderCheckedLists, setGenderCheckedLists] = useState<string[]>([
    "MALE",
    "FEMALE",
  ]);
  const [adCheckedLists, setAdCheckedLists] = useState<string[]>([
    "IMAGE",
    "VIDEO",
  ]);
  const [remarkCheckedLists, setRemarkCheckedLists] = useState<string[]>([
    "CONNECT",
    "EXPOSURE",
    "CLICK",
    "PLAY",
    "SKIP",
    "VISIT",
  ]);

  // 검색창 입력글자 20자 제한
  const inputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.value.length > 20) {
      return;
    }
    setInputValue(e.target.value);
  };

  // 검색 초기화 버튼 핸들러
  const inputInitialize = () => {
    setInputValue("");
    setStartDate(defaultDate);
    setEndDate(new Date());
    setGenderCheckedLists(["MALE", "FEMALE"]);
    setAdCheckedLists(["IMAGE", "VIDEO"]);
    setRemarkCheckedLists([
      "CONNECT",
      "EXPOSURE",
      "CLICK",
      "PLAY",
      "SKIP",
      "VISIT",
    ]);
  };

  // 날짜 제한
  function maxDateRestrict(startDate: Date): Date {
    let moreOneYear = new Date(startDate.valueOf());
    moreOneYear.setDate(moreOneYear.getDate() + 365);

    if (moreOneYear > new Date()) {
      return new Date();
    } else {
      return moreOneYear;
    }
  }

  // 필터링 핸들러
  const changeHandler1 = (target: boolean, id: string): void => {
    if (target) {
      setGenderCheckedLists([...genderCheckedLists, id]);
    } else {
      if (genderCheckedLists.length === 1) {
        return;
      } else {
        setGenderCheckedLists(
          genderCheckedLists.filter((el: string) => el !== id),
        );
      }
    }
  };

  const changeHandler2 = (target: boolean, id: string): void => {
    if (target) {
      setAdCheckedLists([...adCheckedLists, id]);
    } else {
      if (adCheckedLists.length === 1) {
        return;
      } else {
        setAdCheckedLists(adCheckedLists.filter((el: string) => el !== id));
      }
    }
  };

  const changeHandler3 = (target: boolean, id: string): void => {
    if (target) {
      setRemarkCheckedLists([...remarkCheckedLists, id]);
    } else {
      if (remarkCheckedLists.length === 1) {
        return;
      } else {
        setRemarkCheckedLists(
          remarkCheckedLists.filter((el: string) => el !== id),
        );
      }
    }
  };

  const DanbiDatePicker = () => {
    return (
      <>
        <DateBoxContainer>
          <DateBox>
            <DatePickerCustom
              dateFormat="yyyy-MM-dd"
              selected={startDate}
              onChange={onChangeStart}
              selectsStart
              startDate={startDate}
              endDate={endDate}
              maxDate={new Date()}
            />
            <CalenderImg src="/calendar.svg" alt="calender" />
          </DateBox>
          <DateToDate>~</DateToDate>
          <DateBox>
            <DatePickerCustom
              dateFormat="yyyy-MM-dd"
              selected={endDate}
              onChange={onChangeEnd}
              selectsEnd
              startDate={startDate}
              endDate={endDate}
              maxDate={maxDateRestrict(startDate)}
              minDate={startDate}
            />
            <CalenderImg src="/calendar.svg" alt="calender" />
          </DateBox>
        </DateBoxContainer>
      </>
    );
  };
  return (
    <>
      <Period>조회 기간</Period>
      <BoxElement>
        <DanbiDatePicker />
        <InputContainer
          inputValue={inputValue}
          inputChange={inputChange}
        ></InputContainer>
        <SearchBtnList inputInitialize={inputInitialize}></SearchBtnList>
      </BoxElement>
      <CheckBoxContent
        genderCheckedLists={genderCheckedLists}
        setGenderCheckedLists={setGenderCheckedLists}
        adCheckedLists={adCheckedLists}
        setAdCheckedLists={setAdCheckedLists}
        remarkCheckedLists={remarkCheckedLists}
        setRemarkCheckedLists={setRemarkCheckedLists}
        changeHandler1={changeHandler1}
        changeHandler2={changeHandler2}
        changeHandler3={changeHandler3}
      ></CheckBoxContent>
    </>
  );
}

 

 

 

 

 

index.tsx

 

import React from "react";

import { CheckBoxContent as CheckBoxPresenter } from "./CheckBox";
import { PropType } from "./Types";

export default function CheckBox(CheckBoxProps: PropType) {
  return <CheckBoxPresenter {...CheckBoxProps} />;
}

 

 

 

 

presenter

 

import React, { ChangeEvent } from "react";
import {
  CheckBoxContainer,
  Lists,
  TitleFirst,
  Title,
  Name,
  List1,
  List2,
  List3,
} from "./Styles";
import { PropType } from "./Types";

export function CheckBoxContent(props: PropType) {
  const {
    genderCheckedLists,
    setGenderCheckedLists,
    adCheckedLists,
    setAdCheckedLists,
    remarkCheckedLists,
    setRemarkCheckedLists,
    changeHandler1,
    changeHandler2,
    changeHandler3,
  } = props;

  const genders = [
    { id: "MALE", name: "남자" },
    { id: "FEMALE", name: "여자" },
  ];

  const advertisings = [
    { id: "IMAGE", name: "이미지" },
    { id: "VIDEO", name: "영상" },
  ];

  const remarks = [
    { id: "CONNECT", name: "접속" },
    { id: "EXPOSURE", name: "노출" },
    { id: "CLICK", name: "클릭" },
    { id: "PLAY", name: "재생" },
    { id: "SKIP", name: "스킵" },
    { id: "VISIT", name: "방문" },
  ];

  return (
    <CheckBoxContainer>
      <Lists>
        <List1>
          <TitleFirst>성별</TitleFirst>
          {genders.map((gender) => {
            return (
              <>
                <input
                  type="checkbox"
                  key={gender.id}
                  checked={
                    genderCheckedLists.includes(gender.id) ? true : false
                  }
                  onChange={(e: ChangeEvent<HTMLInputElement>) => {
                    changeHandler1(e.currentTarget.checked, gender.id);
                  }}
                />
                <Name>{gender.name}</Name>
              </>
            );
          })}
        </List1>
        <List2>
          <Title>광고종류</Title>
          {advertisings.map((advertising) => {
            return (
              <>
                <input
                  type="checkbox"
                  key={advertising.id}
                  checked={
                    adCheckedLists.includes(advertising.id) ? true : false
                  }
                  onChange={(e: ChangeEvent<HTMLInputElement>) => {
                    changeHandler2(e.currentTarget.checked, advertising.id);
                  }}
                />
                <Name>{advertising.name}</Name>
              </>
            );
          })}
        </List2>
        <List3>
          <Title>비고</Title>
          {remarks.map((remark) => {
            return (
              <>
                <input
                  type="checkbox"
                  key={remark.id}
                  checked={
                    remarkCheckedLists.includes(remark.id) ? true : false
                  }
                  onChange={(e: ChangeEvent<HTMLInputElement>) => {
                    changeHandler3(e.currentTarget.checked, remark.id);
                  }}
                />
                <Name>{remark.name}</Name>
              </>
            );
          })}
        </List3>
      </Lists>
    </CheckBoxContainer>
  );
}

 

 

 

 

type

 

export interface PropType {
  genderCheckedLists: string[];
  adCheckedLists: string[];
  remarkCheckedLists: string[];
  setGenderCheckedLists: React.Dispatch<React.SetStateAction<string[]>>;
  setAdCheckedLists: React.Dispatch<React.SetStateAction<string[]>>;
  setRemarkCheckedLists: React.Dispatch<React.SetStateAction<string[]>>;
  changeHandler1: (target: boolean, id: string) => void;
  changeHandler2: (target: boolean, id: string) => void;
  changeHandler3: (target: boolean, id: string) => void;
}

'🤹🏻‍♀️ Javascript > 🥎 Typescript' 카테고리의 다른 글

[TS] 조건부 타입  (0) 2022.05.07
[TS] 제네릭  (0) 2022.05.07
타입 추론, 타입 단언  (0) 2022.03.06
타입스크립트 에러  (0) 2022.02.25
material ui - Pagination  (0) 2022.02.25