개발 저장소/개발 지식 저장소

[React.js] useRef로 이미지 업로드를 하며 알게된 것들

이거비버 2023. 1. 6. 18:37
반응형

책을 보며 useRef를 봤을 때 크게 와닿지 않았다.

적당히 재 랜더링 방지해주는구나..

컴포넌트가 랜더링이 돼도 계속 남아있으니 메모리를 차지하겠구나.. 하고 넘어갔다.

 

회사의 신규 프로젝트에서 프론트엔드 & 백엔드 간 이미지 파일을 전송하는 기능이 필요해서 구글링을 해보니 언제 쓰는건가 궁금했던 useRef를 쓰더라.

 

const ButtonInputImage = (props) => {
  const [imgFile, setImgFile] = useState("");
  const imgRef = useRef();
  const textRef = useRef();

  const saveImgFile = () => {
    const file = imgRef.current.files[0];
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onloadend = () => {
      setImgFile(reader.result);
    };
  };
  console.log("ButtonInputImage 랜더링");
  return (
    <>
      <CenterIdv>
        <Img src={imgFile ? imgFile : `/img/logo192.png`} alt="프로필 이미지" />
        <Label htmlFor="imageUpload">{props.title}</Label>
        <Input
          type="file"
          id="imageUpload"
          accept="image/*"
          onChange={saveImgFile}
          ref={imgRef}
        />
      </CenterIdv>
    </>
  );
};

 

1. input 핸들링을 위한 useRef() 참조 객체와 img 핸들링을 위한 useState를 선언한다.

2. <input>에 ref prop으로 imgRef를 전달한다

 -> imgRef의 current 속성을 통해 <input>엘레먼트에 접근할 수 있다.

3. onChange prop으로 saveImgFile 함수를 불러온다

4. 함수 안에서 imgRef 참조 객체에 접근한다. 필요한 데이터는 current.files에 있다.

console.log(imgRef)

5. FileReader() 의 객체 const reader를 생성한다.

 -> FileReader : 웹이 비동기적으로 데이터를 읽기 위하여 파일을 가리키는 File객체를 이용해 파일 내용을 읽거나 저장시키는 함수.

6. FileReader()의 메서드 중 readAsDataURL()로 파일을 읽는다.

 -> 읽은 후 console.log(reader)를 찍어봤는데 사진 정보가 어디 들어가는지 몰라서 찾아보니 바이너리 파일을 Base64 Encode 문자열로 반환하는 메소드라고 한다. 

** Base64 는 0,1로 이루어진 Binary 데이터를 아스키 코드 일부와 일대일로 매칭되는 문자열로 단순 치환되는 인코딩 방식이라고 함.. 해당 값은 reader.result에 저장된다.

7. FileReader() 이벤트핸들러 중 onloadend를 활용해 동작이 성공적으로 완료됐을 때 useState 실행 함수에 reader.result를 넣어 imgFile의 상태를 변환시켜준다.

8. imgFile이 변경되면 useState에 의해 재랜더링이 이루어지고 Img태그의 src에서 result 값을 처리해준다.

 -> imgFile? 은 삼항연산자로써 imgFile이 truethy 하면 컬럼(:)의 좌측을 실행하고 falsy하면 우측을 실행한다.

 -> falsy는 불리언 문맥에서 false로 평가되는 값으로 0, false, null, undefined 는 false 값으로 치환된다.

 -> 어떤 값이 들어온다면 truthy하기 때문에 true로 치환된다.

 -> 즉, result 값이 안 들어온 상태면 이미지를 기본 이미지로 올리고, result 값이 truthy하게 변하면 result 값을 src에 넣어주면 이미지가 로딩된다.

 

 

성공적으로 이미지를 로딩한 후 실제로 useRef의 함수는 해당 객체의 변화가 없는 상태에서 재랜더링 할 때 실행이 안 되는지 콘솔을 찍어봤다.

재랜더링을 일으키기 위해 input에다가 useState를 걸어놓고 타이핑 할 때마다 재랜더링 되게 해놨다.

타이핑으로 랜더링 되는 동안 ref 함수는 랜더링되지 않았다.
사진을 바꾸니 ref 함수가 실행됐다.

 

 

 

기능을 구현하는데에는 얼마 걸리지 않는데 어떤 프로세스로 동작하는지 아는것은 꼬꼬무처럼 질문이 꼬리에 꼬리를 물어버린다. 그래서 공부하는 재미가 있다.

 

 

반응형