DEVELOP
article thumbnail

문제상황

이제 배포를 거의 앞두고 있고, 기획자 분과 디자이너 분께서 QA 리스트를 작성하고 첫 QA를 진행했다.

그 중 나온 문제 하나 .. 일기 작성의 내용 부분에서 우리가 내용의 글자 수를 80자로 제한하기로 했고, 

해당 textarea에 maxLength를 80로 주어서 잘 작동되는 것을 확인했다. 

그런데, 아래와 같이 작동이 안된다는 피드백이 있었다. 나 확인했는데 .. ? ? 

그리고 나서 내가 해보니까 안된다... 근데 한글에서만 안된다.

아마도 개발 단계에서 워낙 이것저것 테스트해보다보니, 아무거나 입력하면서 테스트를 했는데, 그때 한글을 pc에서 안해봤던 것 같다.

모바일에서 한글이 잘 제어가 되길래 잘 되는 줄 ... 알았다.

각각 한글/영어/숫자 테스트

위처럼 한글에서는 80자를 넘어도 1글자가 더 입력이되어, 아래 현재 글자 수가 81자까지 되는 것을 확인할 수 있고,

영어나 숫자에서는 80자가 되면 더 이상 어떤 입력도 불가하다. 

 

문제원인

HTML input과 textarea의 maxLength 계산 방식은 UTF-8 기준이다. (크롬 기준)

즉, 한글/숫자/영어 에 따라서 다르게 계산될 수 있다는 이야기이다.

 

그리고 또 한가지, 이 계산 기준은 브라우저에 따라 다르다.

아래는 아이폰 사파리에서 해당 기능을 테스트했을 때이다.

80자가 넘으면 더 이상 써지지 않도록 동작한다.

하지만, 마지막 글자가 입력하는 대로 계속 바뀌게 되는 현상은 존재한다. 

모바일 사파리에서 한글 테스트

결론

이처럼 브라우저에 따라 다르게 동작하므로, 모든 브라우저에서 동일하게 작동할 수 있도록 설정하는 과정이 필요하다. 

해결방법

일기 내용을 업데이트 하기 전에, 최대 글자 수가 넘었으면, slice해준 후 업데이트 되도록한다.

 

코드를 수정하다보니, 80이라는 최대 글자 수가 나중에 변경될 가능성이 있으므로, 따로 상수 MAX_CONTENT로 지정하고 코드를 수정해주었다.  

/* 일기 내용 MAX_CONTENT_LENGTH 보다 넘으면 slice 후 업데이트 */
  
  const handleContentValue = (e: ChangeEvent<HTMLTextAreaElement>) => {
    if (e.target.value.length > MAX_CONTENT_LENGTH) {
      e.target.value = e.target.value.slice(0, MAX_CONTENT_LENGTH);
    }
    updateField("contents", e.target.value);
  };
  
  
  
 //  ...
  
  
  /* onChange 함수로 handleContentValue */
        <textarea
          value={diaryData.contents}
          onChange={handleContentValue}
          placeholder="내용 쓰기"
          maxLength={80}
          ....
        />

나의 경우에는 state를 객체 형태로 저장하고 관리하기 위해서 아래와 같은 updateField 함수가 존재해서 위처럼 작성했으나,

일반적인 경우에는 setState(e.target.value) 으로 값을 변경하면 된다. 

  /* 다이어리 데이터 state 업데이트 함수 */
  const updateField = <K extends keyof DiaryLocalstorageType>(
    field: K,
    value: DiaryLocalstorageType[K],
  ) => {
    setDiaryData({ ...diaryData, [field]: value });
  };

글자 수 제어 이제 잘된다! 

결과

profile

DEVELOP

@JUNGY00N