코딩/위코드 코딩학습

[위코드] TIL(Today I am Learned) -37(마우스 이벤트 해결)

카슈밀 2020. 8. 31. 03:16
반응형

아까전에 TIL을 다 쓰고 잠자러가기전에 조금만 더 만져보기로 했는데,

이게 왠걸 바로 해결.

바로 해당값에 직접 접근하려고 했던 것이 문제였다.

 

달력창을 호출하면서 아무 생각없이 조물딱 거리다가 불현듯 생각이 났는데,

처음에는 달력을 호출해서 나가도 안꺼지는건가 했는데, 마우스를 달력 선택범위 밖으로 꺼내보니 잘 작동하더라.

즉, 마우스 이벤트는 정상적으로 작동되고 있었고,

단지 날짜를 클릭했을 경우 꺼지지 않는 게 문제였다는 것을 인식하였다.

이를 해결하기 위해서

datepicker 안에서는 직접 접근이 어렵기때문에 이를 해결하기 위해서 useEffect를 만져보았다.

이전에 작성한 내용에서 해당 날짜의 변화값을 인지하는 useEffect에서 해당 내용을 추가하였다.

날짜 코드

  //날짜 형식변환기, 마우스 이벤트 감지
  useEffect(() => {
    setStartchange({"startDate" : moment(startDate).format('YYYY-MM-DD')});
    setEndchange({"endDate" : moment(endDate).format('YYYY-MM-DD')});
    if( mini === true )
      setMini(false);
    if( maxi === true )
      setMaxi(false);
  }, [startDate, endDate])

그것은 바로 날짜값이 변화하는 곳을 감지하는 곳 아래에 setMini, setMaxi를 작동하게 하였다.

(문제는 useEffect의 의존성 함수부분에서 오류가 난다.

왜냐하면 의존성 배열에서 바뀜을 감지하는데 

mini, maxi를 내부에 넣었기에 만약 의존성에다 넣어서 변화를 인식하면

마우스 이벤트가 바로꺼져버리는 문제가 발생하여 집어넣지 않았는데, 

그런 이유로 경고창이 뜨는 이유를 알지만, 넣을 수 없는 상황이다. 
이것을 무시하는 문법을 적을까말까 고민중) 

원래는 maxi? null : setMaxi(false); 이렇게 구현하려 했는데, 안타깝게도

Expected an assignment or function call and instead saw an expression no-unused-expressions

문구가 보여지면서 오류를 뿜뿜하길래 안된다고 하여 별수 없이 조건문으로 구현하였다.

youtu.be/1DX9AWRSE5Y

마우스 이벤트 오류 해결

짜잔! 숫자를 클릭하면 바로 해당 이벤트가 false로 바뀌어 자동으로 꺼지게 만들었다.

이걸 구현하려고 4일정도 고민했다. 문제가 뭘까? 하고 바로 해결할 수가 없어 다른 것부터 먼저 해결하였는데,

이게 지금 해결된 문제에 연관되어 있다는 것이 소름이었다.

무협지에서 무공을 익힐때 결국의 끝은 만류귀종(萬流歸宗)이라 했듯이

사이트를 만드는 것도 결국 다른 것을 해결하다가 막혀 다른 것을 먼저 해결하고 다시 보면

결국 막혔던 곳에서 이전에 했던 모든 것이 연관되어 있다는 것을 인식하게 된 경험이 아닐까 싶다.

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

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')});
    if( mini === true )
      setMini(false);
    if( maxi === true )
      setMaxi(false);
  }, [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)=> {
                  return(
                    <Inputlist key={el.id}>
                      <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