본문 바로가기
개발 Study/React

[React] UseEffect, UseRef 사용법

by jiyoon_92 2022. 7. 29.
반응형

react

React에서 사용하는 Hook 중에서 UseEffect와 UseRef에 대해서 좀 더 알아보고 정리해보는 시간을 갖고싶어서 이 글을 작성한다. 

https://ko.reactjs.org/docs/hooks-effect.html

 

Using the Effect Hook – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

1. UseEffect란?

의존값으로 Props나 State등을 배열로 받아 해당 값이 변할 경우 UseEffect()의 첫번째 인자로 받은 함수를 실행시킬 수 있다. 밑에 세 가지 방법으로 사용되는데

1-1. 최초 렌더링 시에만 실행시키고 싶은 경우

useEffect의 두번째 인자로 [] 빈 배열을 설정해주면 최초 렌더링 시에만 한번 수행한다. 아래 예제는 최초 진입 시 그룹과 방 정보를 api를 통해 가져온 후 소켓 연결까지 하는 코드다.

  const updateInitState = () => {
    fetchGroups().then((groupData) => {
      console.log('group data in', groupData);
      setGroup(groupData);
      fetchRooms().then((roomData) => {
        console.log('room data in', roomData);
        setRoom(roomData);
        setLoaded(roomData !== undefined)
        if (roomData !== undefined) {
          initSocketConnection();
        }
      })
    });
  }  
  useEffect(()=>{
    updateInitState();
  }, []);

 

1-2. 의존 값 변경 시 실행시키고 싶은 경우

useEffect의 두번째 인자로 [의존값, 의존값, ......] 배열을 설정해 주면 배열 안에 있는 의존 값(State or Props...etc) 변경 시 함수가 실행된다. 이건 마치 ECS 시스템에서 Component가 변경되면 지켜보던 System이 돌아가는 것과 비슷하다. 

아래 예제는 대화방 내에서 방 ID나 유저 변경 시 소켓을 통해 유저가 입장한 것을 알리고 대화 목록을 업데이트 해주는 기능이다.

    useEffect(()=>{
      initSocketConnection();
      if (roomId !== null && roomId !== undefined) {
        socket.emit('joinRoom', roomId, currnetUser);
        var date = new Date();
        var time = date.getTime();
        fetchChats(roomId).then((res) => {
          var result = res.filter((chat) => {
              var d = new Date(chat.createAt);
              return d.getTime() < time;
            }).map(chat => {
            return({name : chat.userName, message : chat.message, datetime :chat.createAt})
            });
          setChat(result);
        }
        );
      }
    },[roomId, currnetUser]);

 

1-3. 렌더링 할때마다 실행시키고 싶은 경우

두 번째 인자에 아무것도 넣지않고 실행시 렌더링될때마다 실행되는 것을 볼 수 있다. 다만 주의할 점은 실행하고 싶은 함수 내에 State변경함수 같은 걸 넣으면 State변경시 재렌더링이 일어나 무한루프에 빠질 수 있으므로 주의해야한다!!

    useEffect(()=>{
		//실행하고싶은 함수 작성
    });

 

2. UseRef란?

특정 Element를 참조할 수 있는 Reference 변수를 선언할 수 있다. 예를들어 부모 컴포넌트가 자식 컴포넌트를 참조하여 자식컴포넌트의 값을 변경할 수 있다.

아래 예제는 특정 div에 스크롤이 가능하도록 설정한 후 채팅 메시지가 업데이트 될때마다 useEffect내에서 스크롤 위치를 맨 아래로 옮길 수 있도록 작성된 코드다.

UseRef로 ref변수 선언 후 , div의 ref={변수} 로 넣어주면 해당 div를 참조할 수 있다.

참조 값의 값을 변경하려면 talkListRef.current 로 받아와 속성 값을 변경 시킬 수 있다.

//UseRef선언
const talkListRef = useRef();
    
//스크롤 위치 업데이트용 UseEffect함수
useEffect(() => {
  if (talkListRef.current) {
      talkListRef.current.scrollTop = talkListRef.current.scrollHeight;
  }
 }, [chat])
    
 //TalkList 컴포넌트
 const talkList = () => {
   return(
     <div className="div-talk-list" ref={talkListRef}>
       {renderChat()}
     </div>
    );
 }

한 번 정리해 놓으니 다음엔 헷갈리지않고 더 잘 쓸 수 있을 것 같다.

반응형

댓글