-
[React] section 11_1Frontend/React 2023. 11. 2. 20:59
Side effect
애플리케이션에서 일어나는 다른 모든 것을 의미
ex) http request를 보내거나 브라우저 저장소에 무언가를 저장하는 것
useEffect hook
두 개의 매개 변수와 함께 호출된다.
첫 번째 매개 변수는 모든 컴포넌트 평가 후에 실행되어야 하는 함수!
두 번째 매개 변수는 지정된 의존성 (의존성으로 구성된 배열)
-> 의존성이 변경될 때마다 함수가 다시 실행된다.
-> 그러므로 함수에 어떤 side effect 코드라도 넣을 수 있다.
-> 컴포넌트가 다시 렌더링 된 경우가 아닌 의존성이 변경된 경우에만 실행된다.
const [isLoggedIn, setIsLoggedIn] = useState(false); const storedUserLoggedInInformation = localStorage.getItem("isLoggedIn"); if (storedUserLoggedInInformation === "1") { setIsLoggedIn(true); }-> 무한루프 가능성!
-> useEffect 사용해야 함
useEffect(() => { const storedUserLoggedInInformation = localStorage.getItem("isLoggedIn"); if (storedUserLoggedInInformation === "1") { setIsLoggedIn(true); } }, []); // 실제로 앱이 시작될 때 한 번만 실행된다. 의존성이 없기 때문에!-> 모든 컴포넌트 재평가 후에 실행된다. (중요!)
-> 의존성이 변경된 경우에만 실행됨!
데이터 가져오기는 side effect (UI와 직접적인 관련이 없다.)
useEffect(() => { setFormIsValid( enteredEmail.includes("@") && enteredPassword.trim().length > 6 ); }, []);-> 이 코드는 컴포넌트가 다시 렌더링될 때마다 다시 실행되고, 여기서 state를 설정하기 때문에 이것은 재렌더링 주기 자체를 트리거 한다.
-> 무한 루프가 발생한다.
-> side effect에서 사용하는 걸 의존성으로 추가하면 된다.
useEffect(() => { setFormIsValid( enteredEmail.includes("@") && enteredPassword.trim().length > 6 ); }, [setFormIsValid, enteredEmail, enteredPassword]);-> setFormIsValid 함수는 생략 가능하다. 이런 state update 함수는 기본적으로 리액트에 의해 절대 변경되지 않도록 보장되기 때문이다.
-> 일반적으로 특정 데이터, 즉 어떤 state나 prop이 변경될 때 로직을 다시 실행하기 위해서도 useEffect는 사용된다.
-> 여기서 확실히 해야하는 것 : useEffect는 side effect를 처리하기 위해 존재한다.
또는 키 입력을 듣고 입력된 데이터를 저장하는 일 (이 또한 side effect이다...) -> 사용자 입력 데이터의 side effect
-> 어떤 액션에 대한 응답으로 실행되는 액션이 있다면 그것은 side effect!
-> 그 때 useEffect가 도움이 된다!!!
종속성으로 추가할 항목 및 추가하지 않을 항목
- 상태 업데이트 기능 (예를 들어 setFormIsValid)
- 내장 API 또는 함수
- 변수나 함수 (구성요소 외부)
는 추가할 필요가 없다.
- 컴포넌트 함수에 정의된 변수
- 상태
- 컴포넌트 함수에 정의된 props 또는 함수
는 추가해야 한다.
디바운싱
사용자 입력을 디바운스(그룹화)
-> 키를 입력할 때 마다 뭔가를 하지 않고 사용자가 타이핑을 일시 중지했을때 하는 것과 같은...
-> setTimeout 사용!!!
setTimeout
-> 브라우저에 내장된 함수
useEffect(() => { setTimeout(() => { setFormIsValid( enteredEmail.includes("@") && enteredPassword.trim().length > 6 ); }, 500); }, [enteredEmail, enteredPassword]);-> 500밀리초 후에만 이 작업을 수행
-> 여기서 중요한 건 타이머를 저장한다는 것!!!
-> 다음에 키가 입력되면 지운다.
-> 즉 타이머가 한 번에 하나만 실행된다.
-> 사용자가 계속 입력하면 다른 모든 타이머는 계속 지워진다.
-> useEffect 함수에서 첫 번째 인수로 전달하는 함수는 반환을 할 수 있다. (함수 자체를 반환해야 한다.)
-> 여기서 반환되는 이 함수는 clean up 함수라고 한다.
-> useEffect가 처음 실행되는 경우를 제외하고 useEffect 함수가 실행될 때마다 그 전에 clean up 함수가 실행된다.
-> 그리고 이 clean up 함수는 특정한 컴포넌트가 DOM에서 마운트 해제 될 때 마다 실행된다. (컴포넌트가 재사용 될 때마다)
-> clean up 함수는 모든 새로운 side effect 함수가 실행되기 전에, 그리고 컴포넌트가 제거되기 전에(예를 들어 로그인 후 컴포넌트가 DOM에서 제거되면) 실행된다!!!
-> 그리고 첫 번째 side effect 함수가 실행되기 전에는 실행되지 않는다.
useEffect(() => { const identifier = setTimeout(() => { setFormIsValid( enteredEmail.includes("@") && enteredPassword.trim().length > 6 ); }, 500); return () => { console.log("clean up"); clearTimeout(identifier); // 새로운 타이머를 설정하기 전에 마지막 타이머를 지운다. }; }, [enteredEmail, enteredPassword]);의존성을 추가하지 않을 시
컴포넌트가 처음 마운트 되었을 때 실행되고, state가 업데이트 될 때마다 실행된다.
-> 모든 컴포넌트 렌더링 주기 "후에" 실행된다.
빈 배열을 추가할 시
컴포넌트가 처음으로 마운트되고 렌더링 될 때만 실행된다. 그 이후의 렌더링 주기에는 실행되지 않는다.
배열에 의존성을 추가할 시
컴포넌트가 처음 마운트 될 때, 또 의존성에 설정한 state가 변경될 때마다 실행된다.
'Frontend > React' 카테고리의 다른 글
[React] Section 11_3 (0) 2023.11.04 [React] Section 11_2 (0) 2023.11.04 [React] section 9, 10 (0) 2023.11.01 [React] section 6, 7 (0) 2023.10.31 [React] section 4, 5 (0) 2023.10.30