728x90


프로젝트를 진행하다보면
"A의 값이 없을 때 B의 값을 보여주세요!!"를 볼 수 있습니다.

이떄 Typescript 를 사용해보신 분들이라면 아시겠지만 ||??를 봤을 것이다.

어떻게 사용하는지는 알텐데 정확히 어떤 점이 다른지가 궁금할 수 있는데,
이 글에서는 그 각각 어떤 효과를 내고, 어떤 의미를 가지는지를 알아보도록 하겠다.

Null병합 연산자( ?? )

개념

Nullish Coalescing Operator으로 불리며 피연산자가 null이거나 undefined라면 해당 피연산자의 대체 값을 사용하는 연산자다.

사용법

const text = null;

console.log(text ?? '값이 없습니다.');

// 출력값 = '값이 없습니다.'

특징

  1. 왼쪽에 있는 피연산자가 null이거나 undefined인 경우에만 false로 인식
  2. 논리연산자 OR(||) 연산자의 특수한 경우이다.
  3. 연산자들중 우선순위가 5번째로 낮으며, ||보다 한단계 낮은 우선순위를 가진다.
  4. AND(&&)와 OR(||)들과 직접 결합하여 사용 못한다.
  5. false로 인식될 수 있는 값들을 false로 처리하지 않는다. ( ex: 0, '' )

논리연산자 OR ( || )

개념

Logical OR으로 불리며 피연산자들 사이에 연결하여 사용하며,
앞의 피연산자가 false인 경우 뒤의 피연산자를 검사, 해당 피연산자가 true인 경우 해당 값을 사용.

boolean과 사용할 경우 boolean값을 반환하지만, 다른 자료형의 값을 사용할 경우 boolean값이 아닌 값을 반환한다.

사용방법

const text = '';

console.log(text || '값이 없습니다.');

// 출력값 = '값이 없습니다.'

특징

  1. 왼쪽에 있는 피연산자의 논리가 false인 경우 우측 피연산자를 출력
  2. false로 인식하는 값은 boolean, '', "", 0, undefined, Nan이 있다

후기

이 글을 작성하게 된 이유는 프로젝트 진행중 ??연산자를 사용한 부분에서 error가 발생하여 해당 문제를 해결하기위해 알아보는 와중 궁금해서 찾아보았다.
두개의 연산자가 서로 비슷한 출력을 한다 하더라도,
세세하게 보면 출력되는 값이 다르다는 것을 알 수 있다.

이로써 두 연산자를 분리하여 적재저소에 잘 사용하길 바란다.

일단 나부터...

728x90

'Front > TypeScript' 카테고리의 다른 글

[React] ImageUpload 여러 기능들  (0) 2024.04.08
728x90


Image를 업로드 한다 할 때 우리는 여러가지 기능들을 기대하게 됩니다.

미리보기 기능이 있으면 올린 파일이 어떻게 보이는지 미리 알 수 있어서 좋고, Drag Drop기능이 있으면 파일을 보다 편하게 업로드 할 수 있고, 이미지 복사하여 붙여넣기 기능이 있다면 더욱 편하게 업로드 할 수 있을 것입니다.

이렇게 Image혹은 파일을 업로드 하는 것을 우리는 일상속에서 많이 찾아볼 수 있습니다.

그리하여 이번에는 Image를 업로드 할 때 많이 접할 수 있는 미리보기, Drag Drop, Copy Paste기능을 정리하여 보겠습니다.


Preview


이미지 미리보기는 요즘 이미지 업로드라면 대부분이 가지고 있는 기능이라 생각합니다.

사실 이미지를 업로드 할때 미리보기를 구현하는 것은 매우 쉬운일입니다.

이미지를 업로드하게 된다면 이미지 파일을 업로드 할 것이고, 우리는 그 이미지를 그냥 화면에 뿌려주기만 하면 되는 것이기 때문입니다.

위와 같이 이미지를 업로드 할경우 우리는 event를 통해 file객체를 얻을 수 있습니다.

이때 file객체를 읽어 화면에 보여주기 위해서는 FileReader Object를 사용하였습니다.
이 FileReader는 비동기로 작동하는 File을 읽을 수 있도록 해주는 기능을 제공해줍니다.

FileReader는 file를 읽어들이게되면 읽을 수 있는 정보를 result에 담아주게 되는데 이를 저장하였다가 <img/> 태그의 src속성에 넣어주면 위 Gif처럼 이미지를 미리보여줄 수 있습니다.

// 파일을 읽어 result데이터를 뽑아내는 코드
const reader = new FileReader();
reader.readAsDataURL(image);
reader.onloadend = () => {
  if(reader.result && typeof reader.result === 'string') setImageReaderPath(reader.result);
}

Drag Drop


사용자가 편하게 이미지를 업로드 시킬 수 있게 도와주는 기능인 Drag Drop기능입니다.
이 기능은 우선 어떤 목적을 가지고 사용할 것인지가 중요할 것 같습니다.

드래그 할 수 있는 영역을 지정해 두고, 해당 필드에만 업로드 할 수 있게 하거나,
원하는 영역을 잡아 해당 영역을 드래그 드랍이 가능한 영역으로 잡는 것 입니다.

똑같은 것 아닌가??라고 생각하실 수 있지만,
코드 상으로 들어가게 되면 조금 달라진다는 것을 알 수 있습니다.

만약 드래그할 수 있는 영역을 따로 지정하여둔다면 코드 상에서 특별한 어려움 없이 해당 영역에만 이벤트 처리를 하면 됩니다.

다만 드래그를 할 수 있는 영역을 지정하지 않고, 전체영역과 같이 영역을 선택한다면, leave event를 조심해야할 것 입니다.
이유는 DragLeave이벤트는 본인 태그를 벗어나버릴 경우 호출되며, 이는 본인 태그의 자식태그로 마우스가 들어가게 되면 해당 이벤트가 발생하여 저와 같이 화면에 회색화면을 띄워주고 싶다 할 경우 문제가 생길 수 있기 때문입니다.

이를 해결하기 위해 저는 Drag영역과 DragLeave영역을 따로 설정하였습니다.

<div
  className={'image_upload_form'}
  onDragEnter={handleDragStart}
  onDrop={handleFileSelect}
  onDragOver={handleDragOver}
>
  {isDragging ? (
    <div
      className="fileDropZone"
      onDragLeave={handleDragLeave}
      >
      <div
        style={{display: "flex"}}
        >이미지를 업로드 해주세요.
      </div>
    </div>
  ) :
  selectImage ? <img src={selectImagePath} alt={'image'}/> : <span>파일 업로드</span>
  }

</div>

위와 같이 DragEnter즉 드래그를 인지하는 영역에 도달하면 isDragging을 활성화 하여 화면을 fileDropZone으로 덮어 드래그하는 도중 자식 필드를 만나 오류상황이 발생하는 경우를 최소화 하였습니다.

앞으로 해결해 나아가야할 부분이기도 하지만 좀더 깔끔하게 영역을 설정할 수 있도록 수정할 예정입니다.

또한 Drag Drop의 경우 웹 브라우저 상에 event가 걸려있어 해당 이벤트들을 중지 시켜주지 않으면 새 탭이 생기며 이미지가 띄워지는 상황이 발생하게 됩니다.

const handleFileSelect = (event: React.DragEvent<HTMLDivElement>) => {
  // console.log('작동?')
  event.preventDefault();
  event.stopPropagation();
  const file = event.dataTransfer.files.item(0);
  if(!file) {
    setIsDragging(false);
    return;
  }
  setSelectImage(file);
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onloadend = () => {
    if (reader.result && typeof reader.result === 'string') setSelectImagePath(reader.result);
  }
  setIsDragging(false);
};

위 코드 중에서 가장 중요한 부분이 2개 있는데, 이는 event에 설정되어있는 고유 동작을 실행하지 않는 설정인 event.preventDefault()event.stopPropagation()입니다.

event.preventDefatul()는 고유적으로 설정되어있는 동작들을 실행하지 않겠다라는 의미를 가지고 있습니다.

고유기능이라함은 a태그로 보았을 때 a태그를 클릭하였을 때 페이지 이동이 되는 고유 기능이 존재하지만 event.preventDefatul()를 사용하여 해당 고유기능을 사용하지 않게 되어 페이지 이동이 되지 않게 하는 것 입니다.

event.stopPropagation()는 클릭 이벤트가 발생시 상위 엘리먼트들에게로 이벤트가 전파되는 것을 방지하는 것 입니다.

쉽게 지금일어나는 일은 여기서만 해결할께요로 봐주면 좋을 것 같습니다.


Copy Peste


복사 붙여넣기 기능입니다.
우리가 채팅에 많이 사용하며, 메일을 보낼때도 많이 사용해 보셨을 기능입니다.

우리가 ctrl + c를 하게되면 클립보드라는 곳에 우리가 복사한 내용이 임시 저장되게 되는데,
이때 우리가 복사한 이미지는 이 클립보드의 item으로 저장이되게 되는 것입니다.

const handlePaste = async (event: React.ClipboardEvent<HTMLInputElement>) => {
        const items = event.clipboardData.items;
        for (let i = 0; i < items.length; i++) {
            const item = items[i];
            if (item.type.indexOf('image') !== -1) {
                const blob = item.getAsFile();
                if(!blob) return;
                const file = new File([blob], blob.name, { type: blob.type });
                setSelectImage(file);
                const reader = new FileReader();
                reader.readAsDataURL(file);
                reader.onloadend = () => {
                    if(reader.result && typeof reader.result === 'string') setSelectImagePath(reader.result);
                }
            }
        }
    }

위와 같이 clipboardData의 item들을 꺼내와 그중 image type인 데이터들만 뽑아내게 됩니다.
이때 저는 file형태로 관리를 하고 있어 file형태로 변형하여 state관리를 하였고, 미리보기 기능을 위해 FileReader를 사용하여 미리보기 데이터를 관리하였습니다.


코드: https://github.com/KrongDev/imageUploadUI

728x90

'Front > TypeScript' 카테고리의 다른 글

[Typescript] Null을 대체하는 값  (0) 2024.04.08

+ Recent posts