Today Sangmin Learned
article thumbnail
728x90

일단 JS + CRA로 수요일 모각코 포스팅에서 구현해야했던 기능 외에 발견되었던 문제는 전부 해결했다.

수요일에 만들었던 코드의 문제는, 아래 세 가지였다.

1. 콤마나 스페이스바를 눌렀을 때 텍스트박스도 비어있게 되어야 정상인데 콤마 및 스페이스바의 값이 텍스트박스에 삽입이 된 채로 비어있게 되었던 문제

2. 영어를 입력했을 때는 콤마(+스페이스바)가 잘 동작하지만 한국어를 입력하고 트리거를 시키려고 하면 꼭 두 번 눌러야만(스페이스바든 콤마든) 트리거가 되었던 문제

3. 배열로 합친 termsArray를 콘솔에 찍으면 방금 입력하고 이벤트를 실행했을 때 그 값도 잘 들어가서 나오는데, setRelatedTerms를 했음에도 불구하고 relatedTerms를 콘솔에 찍으면 그 값이 바로 들어가지 않았던 문제(이건 문제는 아니었지만..)

 

1. 텍스트박스 이벤트 진행 후 콤마와 스페이스바가 입력된 채로 남아있었던 문제

이건 onKeyPress 이벤트의 문제였다. onKeyPress 이벤트에서는 기본적으로 ASCII 코드를 사용하기 때문에 e.keyCode가 아닌 e.charCode로 불러온다. 그래서 콤마도 charCode는 44인데 keyCode로 하면 188이다. 어쨌든.. 이부분은

  const onKeyPress = (e) => {
    if (
      (e.charCode === 44 || e.charCode === 13 || e.charCode === 32) &&
      trimmedInputTerm
    ) {
      onClick();
    }
  };

이렇게 되었던 부분에서

  const onKeyUp = (e) => {
    if (
      (e.keyCode === 188 || e.keyCode === 13 || e.keyCode === 32) &&
      trimmedInputTerm
    ) {
      onClick();
    }
  };

이렇게 바꿔주고, onKeyPress={onKeyPress}를 onKeyUp={onKeyUp}으로 바꿔주니 해결되었다. 앞으로.. 최대한 onKeyPress보다는 onKeyDown이나 onKeyUp을 사용해야겠다고 생각했다.

 

2. 텍스트박스에서 한국어는 트리거 명령 키를 두 번 입력해야만 됐던 문제

이 역시 onKeyPress의 문제였다;; 1번과 같은 이유이므로 해결책도 같다. 위에서 했던대로 하니까 해결

3. termsArray와 relatedTerms를 콘솔에 찍은 결과가 달랐던 문제

아래 이미지를 보면, "ㅁ"을 입력하고 트리거했을 때 위에는 relatedTerms를 concat하여 배열로 합친 termsArray를 콘솔에 찍은 것이고 아래는 setRelatedTerms(termsArray)를 하고 난 뒤에 콘솔에 찍은 것이다.

이 부분은, setState의 경우 직후에 바로 반영되는 것이 아니라 잠깐 대기시간을 거치고 반영이 되기 때문에, 함수 내부에서 콘솔을 찍으면 아직 반영이 되어있지 않은 상태라고 한다.

이 부분에 대한 확실함을 얻기 위해 함수 바깥에서 다시 한 번 relatedTerms를 찍어본 결과 잘 나왔다.

  const onClick = () => {
    for (let i = 0; i < relatedTerms.length; i++) {
      if (relatedTerms[i].text === trimmedInputTerm) {
        setInputTerm("");
        alert("중복");
        return;
      }
    }
    const termsArray = relatedTerms.concat({
      id: id,
      text: inputTerm.trim().replace(/[^ㄱ-힣a-zA-Z0-9+#]/gi, ""),
    });
    setRelatedTerms(termsArray);
    console.log(termsArray);
    console.log(relatedTerms);
    setId(id + 1);
    setInputTerm("");
  };
  console.log(relatedTerms);

함수 안 termsArray, 함수 안 relatedTerms, 함수 밖 relatedTerms

이렇게 해서 일단 .. 어느정도 구색을 갖추게 되었고, 마지막으로 팀원 형이 도와줘서 해결한 부분이 있다. 이부분은 해야지 하고 생각했던 건 아니고, 좀더 매끄럽게 하기 위해서 넣은 부분이다.

  const onChange = (e) => {
    const lastIdx = e.target.value.length - 1;
    if (e.target.value[lastIdx] === "," || e.target.value[lastIdx] === " ")
      return;
    setInputTerm(e.target.value);
  };

내가 input으로 넣은 값의 가장 마지막 값, 그러니까 인덱스가 (input 길이 - 1)인 값을 변수로 지정하고 저 값에 콤마나 공백이 들어갔을 때 함수를 끝내버리는 것이다. 이말은 즉 input값의 마지막에 콤마나 공백(onClick 함수를 트리거시키는 값)이 들어갈 경우 반영하지 않겠다는 뜻이다.

 

말을 어렵게 적은 것 같은데, 움짤로 보면 차이가 확 느껴진다.

해당 처리를 해주기 이전에 그냥 바로 inputTerm을 e.target.value로 정해버린다면, 콤마나 공백이 잠깐 input에 들어왔다가 사라지지만

처리를 해주고 나면 콤마와 공백이 뜨지 않는다.

 

아무튼 이렇게.. CRA + JS를 사용한 관련용어 구현은 마무리를 하고, 내일 모각코 시간에는 이 CRA + JS로 만든 것을 타입을 입혀서 TS로 바꿔봐야겠다. 그리고 이걸 마치면 이제 본격적으로 개발용어사전 구현 작업이 시작된다.

profile

Today Sangmin Learned

@steadily-worked

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!