[포스코x코딩온] 웹개발자 풀스택 과정 9기 12주차 회고록 - React useEffect

🤔 useEffect 란?

모든 컴포넌트에는 생성되고 업데이트 되고 사라지는 생명주기를 가지고 있다. 이를 각각 Mount, Update,UnMount로 부른다. 

 

Mount : DOM이 생성되고 웹 브라우저 상에 나타남.
Update : Props or State가 바뀌었을 때 업데이트 함.
Unmount : 컴포넌트가 화면에 사라질 때.

 

이 처럼 컴포넌트의 생명주기를 역할을 하는 것을 useEffect()함수를 사용해서 조절할 수 있다. 

 

✏️ 사용 방법

1. 기본 형태

useEffect(function,deps)

● function : 랜더링 이후 실행할 함수를 써준다.

● deps : function을 실행 시켜줄 조건을 써준다. 배열 형태로 사용한다. 이 값의 따라 useEffect가 실행될지 안될지를 판단한다. 

 

2. 컴포넌트가 처음 한번만 Mount 될 때

useEffect(()=>{
	console.log("생성될 때 한번만");
},[])

 

deps에 빈 배열을 넣어주면 된다. 이러면 생성될 때 단 한번만 실행되고 useEffect가 실행되지 않는다.

 

3. 컴포넌트가 렌더링 될 때 마다

useEffect(()=>{
	console.log("컴포넌트가 렌더링 될 때마다");
})

deps에 아무값도 안넣어주면 컴포넌트가 렌더링 될 때 마다 useEffect가 실행된다.

 

4. 컴포넌트가 업데이트 되었을 때

const [status,setStatus] = useState("")

useEffect(()=>{
	console.log("생성될 때 한번만");
},[status])

deps에 props값을 넣어주면 useEffect는 props값이 변경될 때만 실행된다. 

 

5. 컴포넌트가 Unmount 되었을 때

useEffect(()=>{
	console.log("컴포넌트가 렌더링 될 때마다");
    return () => {
    	console.log("컴포넌트 사라짐..");
    };
})

useEffect함수에 return 함수를 쓰면 컴포넌트가 unMount되었을 때 return 함수가 실행된다. 

 


useEffect에 대한 정보를 찾다가 한가지 새로운 사실을 발견했다. 

 

useEffect 실행 시점 

컴포넌트가 Mount, Update, Unmount 될 때 실행 된다고 했으나 이 개념이 잘 잡히지 않았다. 렌더링 되면서 함께 실행되는 것인지, 렌더링 된 후에 실행되는 것인지 의문이었다.

사실 지금까진 아무 생각없이 썻는데 한 블로그를 보면서 의문이 들었다. 

 

예시1. Mount 되었을 때 

import { useEffect } from 'react';

function App() {
  console.log('1');

  useEffect(() => {
    console.log('mount');
  }, []);

  console.log('2');

  return <div className='App'>
  </div>;
}

 

이렇게 코드가 짜여졌을 때 출력 순서는 어떻게 될까..?🤔

나는 당연히 1 - "mount" - 2 순으로 될 줄 알았다. 하지만 출력 순서는 내 생각과 달랐다.

 

 

1 - 2 - "mount" 순으로 실행된다. 

컴포넌트가 렌더링 될 때 동시에 useEffect가 실행되는 것이 아닌, 컴포넌트의 렌더링이 끝난 후 useEffect가 실행되는 것을 알 수 있다.

 

update될 때나 unmount 될 때도 상황도 있으나 블로그 길이가 길어질 거 같으니 이 블로그를 보고 참고 하자!!

 

 

🔥 실습

이번 실습은 백엔드 데이터를 axois를 활용해서 가져오는 연습을 해볼 것이다. 

이는 실제 현업에서도 사용하는 방식이라고 리더님이 말해주셨다. 그래서 더 관심을 가지고 실습을 해보았다.

 

● 데이터

https://jsonplaceholder.typicode.com/users

데이터는 임의의 데이터를 제공하는 사이트에서 받아서 활용할 것이다.

여기에 존재하는 데이터를 axios의 "get"방식으로 받아서 렌더링 해줄 것이다.

 

 

1. 컴포넌트 만들기

export default function UpdateList() {
  // 배열을 추가하고 싶은면 무조건 초기값을 빈배열로 선언
  const [users, setUsers] = useState([]);

  return (
    <>
      
    </>
  );
}

기본적인 틀을 만들어 준다.

users에는 백엔드에서 가져온 데이터를 넣어줄 예정이다.

 

2. 데이터 불러오기

 

→ 첫번째 실패..

 

처음엔 axios로 데이터를 바로 가져오면 될 거 같았다. 

 

useEffect(() => {
    const result = axios({
      method: 'GET',
      url: 'https://jsonplaceholder.typicode.com/users',
    });
    setUsers(result.data);
    console.log('users 배열', users);
  }, []);

 

그래서 useEffect안에 다이렉트로 axios를 사용해서 useState안에 넣어주었다.  

 

 

하지만 위에 사진과 같이 콘솔로 찍어보니 아무런 값도 들어가지 않았다. 해결책을 찾다가 비동기방식 때문이라고 생각하고 수정을 해봤다. 

 

 

→ 두번째 실패..

async/await 을 써서 동기 방식을 바꾸면 제대로 들어갈 거 같았다.

 

useEffect(async () => {
    const result = await axios({
      method: 'GET',
      url: 'https://jsonplaceholder.typicode.com/users',
    });

    setUsers(result.data);
    return () => {
      console.log('연결 해제 완료');
    };
  }, []);

 

그래서 useEffect()함수에 async/await 함수를 써서 동기 방식으로 바꿔봤다. 하지만 이렇게 실행하니 에러가 생겨 실행 조차되지 않았다.

 

 

이유는 단순했다. useEffect()함수에는 async/await 을 사용할 수 없다는 것이다. 해결 방법을 찾다가 useEffect()함수 밖에서 axois를 사용하는 함수를 만들어서 useEffect()함수 안에서 async/await을 실행시키는 방법과 useEffect()함수 안에  다이렉트로 즉시 실행 함수를 만드는 것이다.

 

👍해결방법

1. useEffect() 밖에 또 다른 함수(axios사용)를 만들어서 useEffect 안에서 함수를 불러와서 async/await 를 실행
2. useEffect() 안에서 즉시 실행 함수(axios 사용)를 만들어서 async/await 를 실행
export default function UpdateList() {
  // 배열을 추가하고 싶은면 무조건 초기값을 빈배열로 선언
  const [users, setUsers] = useState([]);

  // DOM 생성할 때 axios로 데이터 불러오기
  useEffect(() => {
    // useEffect는 비동기 함수를 직접적으로 지원하지 않음.
    // 비동기함수를 사용하려면 내부에 비동기 함수를 정의하고 바로 호출
    const axiosUser = async () => {
      const result = await axios({
        method: 'GET',
        url: 'https://jsonplaceholder.typicode.com/users',
      });
      setUsers(result.data);
    };
    axiosUser();
  }, []);

 

이처럼 useEffect()안에 함수를 만들고 그 안에 async/await를 사용해 데이터를 불러오니 잘 불러와졌다. 

 

 

데이터가 잘 불러와진 모습을 볼 수 있다.