코딩/위코드 코딩학습

[위코드] TIL(Today I am Learned) -35(날짜 포맷 변환)

카슈밀 2020. 8. 29. 23:40
반응형

- 오늘의 할일.

  • 달력 인풋창의 마우스이벤트 발생시 다른 곳을 가도 안꺼지는 오류 수정
  • 달력 반환값을 표현방식을 변환하여 출력하기
  • 보내기 버튼 구현시에 해당 state값을 죄다 보내주기.

- 오늘한 일 

  • 달력 반환값을 표현방식을 변환하여 출력하기(회원가입, step1 페이지 진행)

- 진행예정 및 진행중

  • 달력 input창 이벤트는 input을 만들었더니 클릭했을시에 같이 호출되는 상황이라 클릭해서 호출 되는 부분을 컨트롤하려고 찾는 중.
  • 보내기 버튼은 처음에는 부모로 state값을 보내서 컨트롤하려고 했는데, 너무 힘들기만 하고 잘 불러오지지도 않아서 그냥 sessionstorage로 보내버림.
  • 보내기 버튼 클릭시 다운로드와 해당 자료들을 모두 보내는 작업 진행중.

나의 오늘의 코드!

왜 useEffect를 아예 습득한 날(?)이라고 볼 수 있기때문이다.

공식 문서를 봐도 잘 몰랐는데, 해당 코드를 작성하면서 완벽하게 useEffect를 이해하게 되었다.

내가 고민하던 부분인 날짜 형식을 변환해야하는데,

아무리 해도 해당 datepicker에서 setState를 돌려 인자를 받을 경우 내가 원하는 방식으로 변환이 되지 않았고,

해당 setState를 돌리는데 있어 넣을만한 자리가 없었기때문이다.

그래서  useEffect를 사용하면 되겠다 싶어서 작성 방법을 찾다가 멘토님(손승현)에게 문의하여 해결하였다.

  //날짜 형식변환기
  useEffect(() => {
    setStartchange({"startDate" : moment(startDate).format('YYYY-MM-DD')});
    setEndchange({"endDate" : moment(endDate).format('YYYY-MM-DD')});
  }, [startDate, endDate])

위 코드의 내용은 일반적으로 호출 하는 날짜 양식을 내 마음대로 변환하기위한 것이다.

왜 이러한 고생을 했냐면, startDate를 저장하는 곳에서 바로 해당값이 변환되지 않기때문이다.

Sat Aug 29 2020 23:30:52 GMT+0900 (대한민국 표준시) 이런 형식으로 출력되다보니 변환이 필요했다.

그래서 해당 값이 저장 되는 startDate의 초기 스테이트 값에 해당하는 부분에 moment.().format('yyyy-mm-dd')를 감싸았더니 new date의 연결이 끊기는지, Invaild Date 오류가 뜨는 상황이었다.

별수 없이 새로운 스테이트 값을 구현하였고, 해당 값을 저장하였다.

문제는 해당 스테이트에 있는 setState들이 작동되지 않는 것이었다.

초기값으로 유지만 되고, setStartchange가 작동되지 않는 것이 문제라고 생각했다.

작동로직

이를 위해 useEffect를 가져왔다.

해당 값이 변화가 감지되면, 자동적으로 setState를 작동하게 구현하였다.

  //날짜 형식변환기
  useEffect(() => {
    setStartchange({"startDate" : moment(startDate).format('YYYY-MM-DD')});
    setEndchange({"endDate" : moment(endDate).format('YYYY-MM-DD')});
  }, [startDate, endDate])

 

useEffect의 기능을 좀 구현하기가 어려웠다.

개념을 이해하지 않은 것도 있었고, 실행하고 싶은 내용을 fetch만 넣는 것으로 알고 있었기때문이다.

이를 알려준 위코드(wecode)의 멘토 손승현님에게 감사합니다.

useEffect(() => {

// 실행하고 싶은 내용

}, []);

다음은 날짜의 출력양식은

Sat Aug 29 2020 23:30:52 GMT+0900 (대한민국 표준시)으로만 출력되고 있었는데,

이를 바꿀 필요가 있었다.

"2020-08-29"와 같은 양식으로 바꾸려면 해당 moment라는 라이브러리를 호출해야한다. 

 

설치방법은 해당 내용을 참조

https://momentjs.com/

 

Moment.js | Home

Format Dates moment().format('MMMM Do YYYY, h:mm:ss a'); moment().format('dddd'); moment().format("MMM Do YY"); moment().format('YYYY [escaped] YYYY'); moment().format(); Relative Time moment("20111031", "YYYYMMDD").fromNow(); moment("20120620", "YYYYMMDD"

momentjs.com

https://github.com/jinyowo/JS-Calendar/wiki/**-moment.js-(%EB%82%A0%EC%A7%9C%EA%B4%80%EB%A0%A8-%EC%9E%91%EC%97%85%EC%9D%84-%EC%9C%84%ED%95%9C-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC)

 

jinyowo/JS-Calendar

2017 FEinternship, simple calendar with javascript - jinyowo/JS-Calendar

github.com

내가 도움을 받은 moment라이브러리 설명서(?)이다.

format은 깔 필요는 없다.

import format from "dfn-fs(?)"; 로 호출할 필요가 없다.

그냥 moment만 호출하면 되더라.

해당 자료값을 수정하여 저장해서 호출 되더라.

작동되는 방식 날짜를 바꾸면 해당 내용으로 바로 바뀌더라.

 

import React, { useState, useEffect } from "react";
import styled from "styled-components";
import DatePicker from "react-datepicker";
import moment from "moment";
import { INPUT_LIST } from "../../../config";

function StepOne(props) {
  const date = new Date();
  const lastYear = date.getFullYear() - 1;
  const defalutYear = date.getFullYear() - 13;
  const [ startDate, setStartDate] = useState(new Date(`${defalutYear}-01-01`));
  const [ endDate, setEndDate] = useState(new Date(`${lastYear}-12-31`));
  const [ mini, setMini ] = useState(false); // 마우스 이벤트 감지
  const [ maxi, setMaxi ] = useState(false);
  const [ check, setCheck ] = useState({}); // format값
  const [ comp, setComp ] = useState(); // 목업데이터 저장소
  const [ startchange, setStartchange ] = useState(); // 시작날짜변환값 저장
  const [ endchange, setEndchange ] = useState(); // 마감날짜 변환값 저장

  //배열 뿌리기
  useEffect(()=> {
    fetch(INPUT_LIST)
      .then(res => res.json())
      .then(res=> {
        setComp(res)
      })
  },[])
  
  //날짜 형식변환기
  useEffect(() => {
    setStartchange({"startDate" : moment(startDate).format('YYYY-MM-DD')});
    setEndchange({"endDate" : moment(endDate).format('YYYY-MM-DD')});
  }, [startDate, endDate])

  //세션스토리지 저장
  useEffect(() => {
    sessionStorage.setItem("startDate", JSON.stringify({startchange}));
    sessionStorage.setItem("endDate", JSON.stringify({endchange}));
    sessionStorage.setItem("check", JSON.stringify({check}));
  }, [startchange, endchange, check])

  // 포맷 저장기
  const valuedetector = (e) => {
    const { name, value } = e.target;
    setCheck({[name] : value})
  }
  
  return(
    <>
      <div>
        <StepOnePart>
          <div>
            <BoldWrite>Step 1:</BoldWrite>
            <SpanTitle> Choose your date range.</SpanTitle>
          </div>
          <DateRangeWrap>
            <DateRangeRow>
              <DateRangeTitle>Date range</DateRangeTitle>
              <DateWrap>
                <div 
                  onMouseEnter={()=>setMini(true)}
                  onMouseLeave={()=>setMini(false)}
                >
                  <DatePicker
                    className="datepickersize"
                    dateFormat="yyyy-MM-dd"
                    selected={startDate}
                    onChange={date => setStartDate(date)} 
                    selectsStart
                    startDate={startDate}
                    endDate={endDate}
                    minDate={new Date("1925-12-31")}
                    maxDate={new Date(endDate)}
                    dropdownMode="select"
                    peekNextMonth
                    showMonthDropdown
                    showYearDropdown
                    placeholderText=" Effective date"
                  />
                </div>
                <HiddenMiniDate mini={mini}>
                  Minimum allowed date: 1925-12-31
                </HiddenMiniDate>
                <SpanBox>to</SpanBox>
                <div
                  onMouseEnter={()=>setMaxi(true)}
                  onMouseLeave={()=>setMaxi(false)}
                >
                  <DatePicker
                    className="datepickersize"
                    dateFormat="yyyy-MM-dd"
                    selected={endDate}
                    onChange={date => setEndDate(date)}
                    selectsEnd
                    startDate={startDate}
                    endDate={endDate}
                    changeMonth="true"
                    changeYear="true"
                    minDate={new Date(startDate)}
                    maxDate={new Date(`${lastYear}-12-31`)}
                    dropdownMode="select"
                    peekNextMonth
                    showMonthDropdown
                    showYearDropdown
                    placeholderText=" Expiration date"
                  />
                </div>
                <HiddenMaxiDate className="maxi" maxi={maxi}>
                  Maximum allowed date: {lastYear}-12-31
                </HiddenMaxiDate>
              </DateWrap>
            </DateRangeRow>
          </DateRangeWrap>
        </StepOnePart>
        <div>
          <MarginTop>
            <div>
              <Strongtitle>Step 2:</Strongtitle>
              <SpanContent> Apply your company codes.</SpanContent>
            </div>
            <div>
              <Unorderedlist>
                {comp && comp.Complist.map((el, index)=> {
                  return(
                    <Inputlist key={index}>
                      <InputBtn 
                        id={el.id}
                        name="comp"
                        type="radio"
                        value={el.value}
                        autocomplete="off"
                        checked={ check && check.comp === el.value}
                        onChange={valuedetector}
                      />
                      &nbsp;
                      <LabelName id="TICKER">{el.id}</LabelName>
                    </Inputlist>
                  )
                })}
              </Unorderedlist>
            </div>
          </MarginTop>
        </div>
      </div>
    </>
  )
}

export default StepOne;

//Step One부분
const StepOnePart = styled.div`
  margin-top: 30px;
`;

const BoldWrite = styled.strong`
  font-size: 20px;
  font-weight : bold;
`;

const SpanTitle = styled.span`
  font-size: 20px;
`;

//데이트피커 부분
const DateRangeWrap = styled.div`
  margin: 0 -15px;
`;

const DateRangeRow = styled.div`
  width: 50%;
  position: relative;
  min-height: 1px;
  padding: 0 15px;
`;

const DateWrap = styled.div`
  display: flex;

  .datepickersize{
    height: 36px;
    padding: 8px 12px;
    font-size: 12px;
    line-height: 1.5;
    background-color: #fff;
    border: 1px solid #ccc;
  }
`;

const DateRangeTitle = styled.label`
  color: black;
  display: inline-block;
  margin-bottom: 0;
  padding-top: 9px;
  height: 32px;
  text-align: right;
  font-size: 14px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
`;

const HiddenMiniDate = styled.div`
  display: ${(props) => (props.mini || props.maxi? "flex": "none")};
  position: absolute;
  justify-content: center;
  align-items: center;
  color: white;
  background-color: black;
  width: 200px;
  height: 39px;
  top: -9px;
  left: -3.5px;
  margin-top: -3px;
  padding: 5px 0;
  opacity: 0.8;
  z-index: 1070;
  line-height: 1.4;
  font-size: 12px;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
`;

const HiddenMaxiDate = styled(HiddenMiniDate)`
  left: 211px;
`;

const SpanBox = styled.span`
  color: #AAAAAA;
  background-color: #eeeeee;
  border: 1px solid #ccc;
  font-size: 14px;
  text-align: center;
  width: 9%;
  line-height: 18px;
  padding: 8px 12px;
  white-space: nowrap;
  vertical-align: middle;
`;

//파트 2부분
const MarginTop = styled.div`
  margin-top: 30px;
`;

const Strongtitle = styled.strong`
  font-size: 20px;
  font-weight: bold;
`;

const SpanContent = styled.span`
  font-size: 20px;
`;

const Unorderedlist = styled.ul`
  margin: 15px 0;
  padding-left: 0;
  list-style: none;
  display: flex;
`;

const Inputlist = styled.li`
  margin-right: 10px;
  padding:0 5px;
  height: 29px;
  display: flex;
  align-items: center;
`;

const InputBtn = styled.input`
  margin: 0;
`;

const LabelName = styled.label`
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 14px;
`;
728x90