TIL: 2022-05-26 React 입문

김하연·2022년 5월 26일
0

TIL: Today I Leaned

목록 보기
16/26

함수형 컴포넌트에서의 Event listener 해제

event listener는 등록되면 반드시 해제되어야 한다.
클래스형 컴포넌트에서는 컴포넌트가 화면에서 사라질 때(unmount 될 때) componentWillUnmount메서드에서 event listener를 해제하는데, 라이프사이클 메소드를 사용할 수 없는 함수형 컴포넌트에서는 event listener를 해제할 때 어떻게 해야할까?

useEffect의 return 함수를 사용하면 된다.

useEffect 함수의 return 안에 clean-up function을 작성하면 된다.
return()=>{} 안에 기존의 이벤트들을 삭제해달라는 코드를 작성하는 것이다.
useEffect 함수 내의 실행 순서는 return()=>{} 안의 내용이 먼저 실행되고 나머지 코드들이 실행된다. return 함수 자체는 unmount시에만 실행되고, mount시에는 실행되지 않기 때문에 component가 unmount될 때 기존에 등록된 이벤트가 삭제되는 것이다.

useEffect(()=>{ 코드 }) // 제렌더링때마다 코드 실행
useEffect(()=>{ 코드 }, []) // mount시 1회 코드 실행
useEffect(()=>{
	return () =>{
      코드
    }
}, []) // unmount시 1회 실행
useEffect(()=>{ 코드 }, [state]) // state값 변경될 때만 실행

// 공통 : useEffect실행 전 다른 이벤트 먼저 동작시키고 싶다면 return()=>{}안에 작성하면 됨

ref를 사용하는 이유

리액트의 경우 컴포넌트 내에 업데이트가 발생할 경우, 바로 DOM에 이 내용을 반영하는 것이 아니라 가상 DOM에 내용을 저장한 후, 업데이트된 부분만 실제 DOM에 적용하는 방식으로 작동한다.
그렇기 때문에 docmuent.getElementsByClassName등의 선택자를 사용해 리액트 내의 요소들을 제어하려고 하면 제대로 작동하지 않거나 의도하지 않은 라이프 사이클 흐름 내에서 이벤트가 발생할수도 있다.
ref는 가상 DOM에 있는 리액트 요소에도 접근이 가능하기 때문에 이와 같은 문제를 방지할 수 있다.
또한 ref는 컴포넌트 라이프 사이클 내에서 유지되는 변경 가능한 변수이며, 변수가 변할 때 렌더링이 추가로 발생하지 않는다. 그렇기 때문에 ref를 활용하면 전체 컴포넌트를 렌더링 시키지 않고, DOM에만 접근하여 내가 원하는 이벤트나 효과를 추가하는 것이 가능하다.


Too many re-renders... 오류 발생하는 이유

<button onClick={clickEvent}></button> // 정상 작동
<button onClick={clickEvent()}></button> // Too many re-renders... 오류 발생

위의 두 가지 경우에서 () 괄호를 붙이느냐 안붙이느냐에 따라 왜 오류 발생 여부가 다른지 이해가 안됐다. 리액트 강의에서 괄호를 붙이면 렌더 되자마자 저 함수가 실행되는거니까 괄호 붙이지 말라고 나왔는데, 바로 실행시키는게 왜 too many re-renders 를 발생시키지? 라는 의문이 들었다.

그래서 찾아본 그 이유..!
위의 함수는 state의 값을 바꾸는 내용의 함수이다.
컴포넌트에서 state의 값이 변경될 경우, 페이지는 리렌더링이 진행된다. 그렇기 때문에 페이지 렌더링 완료 > state 변경 함수 바로 실행 > state 변경으로 페이지 리렌더링 > state 변경함수 바로 실행 > state 변경으로 페이지 리렌더링... 이 과정이 무한 반복되기 때문이라고 한다!

뭔가 당연한 논리였는데, 그 이유에 의문을 품고 직접 파악하고나니 이제서야 이해가 된 것 같다.


리액트에서 public폴더에 이미지 사용

리액트로 개발한 프로젝트는 배포 전 build 작업을 해야하는데, 작업 파일들을 한개의 파일로 압축해주는 과정이다. 브라우저는 html, css, javascript 언어를 사용하기 때문에 props, state 등 리액트의 자체 언어를 컴파일 하는 작업이라고 볼 수 있다.
이 때 src 폴더에 들어있는 코드와 파일들은 모두 압축이 되는데 public 폴더에 있는 것들은 압축이 되지 않기 때문에, 형태를 보존하고 싶은 파일은 public 폴더에 넣으면 된다.
이미지, txt, json 파일 등 수정이 필요없는 static 파일들의 경우 public 폴더에 보관해도 상관이 없다.

<img src="/logo192.png" /> 
<img src={process.env.PUBLIC_URL + '/logo192.png'} /> 

public 폴더 경로는 root 경로로 지정을 하면 되고, 위 코드에서 두가지 방식 모두 정상적으로 작동이 되지만 좀 더 권장하는 것은 두번째 방법이다.

예를 들어 리액트로 만든 html 페이지를 webpage.com 경로에 배포를 하게 된다면 문제가 없지만, webpage.com/main/ 이라는 경로에 배포를 하게되면 파일의 경로를 찾을 수 없다고 나올 가능성이 있다.
그렇기 때문에 정확한 경로를 짚어주는 process.env.PUBLIC_URL 라는 문구를 추가하면 좋은데, 만약 root 경로가 아닌 하위 경로에 페이지를 배포할예정이 없다면 문제가 되진 않는다.

0개의 댓글