이롭게 현명하게

[React] 리액트 useEffect 본문

웹 개발/React

[React] 리액트 useEffect

dev_y.h 2024. 1. 4. 18:11
728x90
반응형

※ 본 포스팅은 윈도우11 환경에서 패스트 캠퍼스 강의를 수강하며 정리한 내용입니다.

 


 

목차

 

useEffect란

import

예시코드

정리

 


 


[useEffect란]

useEffect는 컴포넌트가 마운트 됐을 때 (처음 나타났을 때) , 언마운트 됐을 때 (사라질 때) , 업데이트될 때 (특정 props가 변경될 때) 특정 작업을 처리하는 방법에 사용한다.

  • 마운트 (mount) : 나타나는 것을 의미한다.
    • props로 받은 값을 컴포넌트의 로컬 상태로 설정
    • 외부 API 요청( REST API 등)
    • 라이브러리(ex. D3, video)를 사용할 때
    • setInterval, setTimeout을 사용할 때
  • 언마운트 (unmount) : 컴포넌트가 사라지는 것을 의미한다.
    • 뒷정리 함수
    • setInterval, setTimeout 을 사용하여 등록한 작업들 clear 하기 (clearInterval,claerTimeout)
    • 라이브러리 인스턴스 제거

 

추가적으로 컴포넌트의 props나 상태가 바뀌어 업데이트될 때도 어떤 작업을 할 수 있고, 업데이트되기 전에도 작업을 할 수 있다.

리렌더링 될 때마다 작업을 등록할 수 있다.

 


[import]

import React,{useEffect} from "react";

 

<형태>

useEffect(()=>{수행해야할 작업},[의존되는 값들의 배열]);

첫 번째 파라미터 : 실행할 함수

두 번째 파라미터 : deps로 의존되는 값들을 이 배열 안에 넣어준다.

만약 의존되는 값들이 비어있다면 컴포넌트가 처음 화면에 나타날 때만 실행이 된다.

 

<useEffect 구조>

useEffect(()=>{
	// mount
	컴포넌트가 생길 때 수행 작업
	return{ // cleanup
	//unmount
	컴포넌트가 사라질 때 수행 작업
	}
},[의존되는 값들]);

의존성을 추가해서 값이 변경되기 직전과 변경된 직후의 값을 제어할 수 있다.

useEffect에서는 함수를 반환할 수 있다. 컴포넌트가 사라질 때의 특정 작업은 함수를 반환해 주면 된다.

이것을 cleanup 함수라고 한다.

useEffect에 대한 뒷정리를 한다고 이해하면 편하다.

<cleanup 함수>

  • useEffect 안에서 return 할 때 실행된다.
  • useEffect의 뒷정리한다. → state에서 값 지울 때 실행

 

useEffect에서 함수가 호출되는 시점에서는 우리의 ui가 화면에 나타난 상태 이후이다.

 

 


[예시코드]

더보기

 

// UserList.js //
import React,{useEffect} from "react";

function User({user, onRemove,onToggle}){
	const {username,email,id,active}=user;
	useEffect(()=>{
		console.log('컴포넌트가 화면에 나타남')
		return ()=>{
			console.log('컴포넌트가 화면에서 사라짐')
		}
	},[]);
	return(
		<div>
			<b 
				style={{
					color: active? 'green': 'black',
					cursor : 'pointer'
				}}
				onClick={()=>onToggle(id)}
			>{user.username}</b> <span>{user.email}</span>
			<button onClick={()=>onRemove(user.id)}>삭제</button>
		</div>
	);
}
function UserList({users,onRemove,onToggle}){
	return(
		<div>
			{
				users.map(
					user =>(<User user={user} key={user.id} onRemove={onRemove} onToggle={onToggle}/>)
				)
			}
		</div>
	);
}
export default UserList;

 

// CreateUser.js //

import React from "react";

function CreateUser({username,email,onChange,onCreate}){
    return(
        <div>
            <input name="username" placeholder="계정명" onChange={onChange} value={username}/>
            <input name="email" placeholder="이메일" onChange={onChange} value={email}/>
            <button onClick={onCreate}>등록</button>
        </div>
    );

}

export default CreateUser;

 

// App.js //

import React,{useRef,useState,useMemo} from "react";
import UserList from "./UserList";
import CreateUser from "./CreateUser";

function App() {
  const [inputs,setInputs] = useState({
    username:'',
    email:''

  });

  const {username,email} = inputs;
  const onChange = e =>{
    const {name,value} = e.target
    setInputs({
      ...inputs,
      [name]:value
    });
  }

  const [users,setUsers] =useState([
    {
        id : 1,
        username : 'uni',
        email : 'uni@gmail.com',
        active : true
    },
    {
        id : 2,
        username : 'dog',
        email : 'dog@gmail.com',
        active : false
    },
    {
        id : 3,
        username : 'cat',
        email : 'cat@gmail.com',
        active : false
    }
]);


  const nextId = useRef(4);
  const onCreate = () =>{
    const user = {
      id: nextId.current,
      username,
      email
      
    }
    setUsers(users.concat(user));
    setInputs({
      username:'',
      email:''
    });
    //console.log(nextId.current)
    nextId.current +=1;
    
  console.log(users)
  }

  const onRemove = id=>{
    setUsers(users.filter(user=>user.id !== id));
  }
  const onToggle = id=>{
    setUsers(users.map(
      user=>user.id===id
      ?{...user,active:!user.active}:user
      ));
  }
  return (
    <>
    <CreateUser username={username} email={email} onChange={onChange} onCreate={onCreate} />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle}/>
    </>

  );
}

export default App;

 

 

  • deps가 비어있는 경우
  • deps에 값이 있는 경우
  • deps값이 없는 경우

 

 

 

 

 

 

 

 

<deps가 비어있는 경우>

import React,{useEffect} from "react";

useEffect(()=>{
	//mount
    console.log('컴포넌트가 화면에 나타남')
	return ()=>{ //unmount
		console.log('컴포넌트가 화면에서 사라짐')
	}
},[]);

의존되는 값들이 비어있다면 컴포넌트가 처음 화면에 나타날 때만 useEffect에 등록한 함수가 실행된다.

 

 

<deps에 특정 값 넣기>

useEffect(()=>{
    console.log('user값이 설정됨')
    console.log(user)
    return () =>{
        console.log('user값이 바뀌기 전')
        console.log(user)
    }
},[user]);

useEffect에 등록한 함수는 [user] 값이 설정되거나 혹은 바뀔 때마다 호출이 된다.

마운트 될 때도 값이 나타난다.

useEffect에 등록한 함수는 특정 값이 업데이트되고 난 직후에 실행이 된다.

useEffect에 deps 배열에다 어떤 값을 넣게 된다면 해당 값이 바뀔 때마다 등록한 함수가 호출된다.

해당 값이 바로 바뀌기 직전에는 설정한 clear 함수가 호출된다.

값이 바뀔 때도 호출이 되지만 처음 나타날 때도 호출이 된다.

useEffect에 등록한 함수에서 props에서 받아온 값을 참조하거나 혹은 useState로 관리하는 값을 참조하고 있는 경우 deps배열을 꼭 넣어줘야 한다.

넣지 않아서 오류가 나타나지는 않지만, 나중에 나타날 수 있으며 값을 넣어야지만 최신의 값을 가리킨다.

 

<deps값이 없는 경우>

useEffect(()=>{
    console.log('user값이 설정됨')
    console.log(user)
    return () =>{
        console.log('user값이 바뀌기 전')
        console.log(user)
    }
});

 

deps 배열을 생략하는 경우는 컴포넌트가 리렌더링 되고 나서 호출된다.

 


리액트에서는 부모 컴포넌트가 리렌더링 되면 자식 컴포넌트 또한 리렌더링 된다.

실제 브라우저에 변화가 발생하는 것은 실제 내용이 업데이트된 경우 내용이 업데이트된 DOM에서만 업데이트된다.

항목이 많아지면 느려질 수 있다.

 

 


[정리]

import React,{useEffect} from "react";
useEffect(()=>{함수},[deps]);

<useEffect 구조>

useEffect(()=>{
	// mount
	컴포넌트가 생길 때 수행 작업
	return{ // cleanup
	//unmount
	컴포넌트가 사라질 때 수행 작업
	}
},[deps]);

<실행할 함수>

  1. 화면이 처음 떴을 때 실행
    1. deps에 [] 빈 배열을 넣을 때
    2. life cycle 중 componentDidmount처럼 실행
  2. 화면이 사라질 때 실행(cleanup 함수)
    1. componentWillmount처럼
  3. deps에 넣은 파라미터값이 업데이트됐을 때 실행
    1. componentDidmount처럼

<cleanup 함수>

  • useEffect 안에서 return 할 때 실행된다.
  • useEffect의 뒷정리한다. → state에서 값 지울 때 실행된다.

<deps>

  • deps에 특정 값을 넣게 되면, 컴포넌트가 마운트 될 때 지정한 값이 업데이트될 때 useEffect 실행
  • deps에 값이 없다면 useEffect가 최신 값을 가리키지 않게 된다.
  • deps에 값이 없다면 컴포넌트가 리렌더링 될 때마다 호출이 된다.
  • deps에 값을 넣는 것을 기본이라고 생각하는 게 좋다.
  • deps에 빈배열 : 처음에만 호출
  • deps에 의존값 존재 : 처음과 지정 값이 변경될 때 호출
  • deps가 아예 없는 경우 : 컴포넌트가 리렌더링 될 때마다 호출

 

 

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

 

 

728x90
반응형
Comments