useEffect / useReducer
[ 기초 지식 ]
component는 lifecycle이 존재
컴포넌트도 인생이 있다.
1. mount (생성, 처음 나타났을 때)
: props로 받는 값을 컴포넌트의 로컬 상태로 설정할 때 / 외부 API요청 (REST API 등, 라이브러리 사용
setInterval을 통한 반복작업 혹은 setTImeout 통한 작업 예약
2. unmount (사라질 때)
: setInterval로 등록한 작업을 clear하기 (clearInterval, clearTimeout), 라이브러리 인스턴스 제거
3. re-rendering (업데이트, 관련된 state가 변경되면 재렌더링)
> component의 인생의 중간중간 hook을 걸 수 있다. (인생에 참견한다)
이를 lifecycle hook이라고 하고, ' detail component등장전에 이것좀 해줘!' ' 업데이트 되고나서 이것좀 해줘!' 이런느낌
class형
componentDidMount (컴포넌트 첫 등장 후 실행할 코드)
componentWillUnmount(컴포넌트 사라지기 전 실행할 코드)
class Detail extends React.Component {
componentDidMount(){
//Detail 컴포넌트가 Mount 되고나서 실행할 코드
}
componentWillUnmount(){
//Detail 컴포넌트가 Unmount 되기전에 실행할 코드
}
}
useEffect
useEffect가 하는일 ?
useEffect hook을 이용하여 react가 컴포넌트 렌더링 이후에 어떤 일을 수행하는지를 지정할 수 있다.
//첫번째 파라미터에는 함수
//두번째 파라미터에는 의존값 들어있는 배열 (deps)을 넣는다.
useEffect(() => {
effect
return () => {
cleanup
}
}, [input])
1. useEffect를 import 해온다.
2. useEffect를 사용하고 콜백함수를 집어넣는다.
3. 콜백함수에는
컴포넌트가 첫 등장해서 로딩 끝난후에 (mount끝났을 때)
컴포넌트가 재렌더링 되고 난 후에 (update 되고난 후에)
실행할 코드를 작성한다.
4. useEffect(() => {
return () => {} 리턴 뒤넣은 함수(cleanup함수)는 컴포넌트가 사라질 때 실행된다.
5. 두번째 파라미터에 의존값 있는배열 (deps)를 넣는다.
비워놓으면 컴포넌트 처음 나타날때만 useEffect 호출된다.
✔️ 마운트 시 하는 작업
- props로 받은 값을 컴포넌트의 로컬 상태로 설정
- 외부 API 요청 (REST API)
- 라이브러리 사용
- setInterval 통한 반복작업 혹은 setTimeout
✔️ 언마운트 시 하는 작업
- setInterval, setTImeout 사용하여 등록한 작업들 clear ( clearInterval, clearTimeout)
- 라이브러리 인스턴스 제거
✔️ deps에 특정 값 넣기
1. 파라미터에 아무것도 안 넣었을 경우
리렌더링 될 때마다 함수 호출 (=모든 component render cycle마다 작동)
1. deps에 빈 배열 - [ ]
mount : 처음 mount 될 때 함수 호출 (리렌더링 시 X )
unmount : cleanup 함수 호출
2. deps에 의존 값 존재 - [dpes]
mount : 처음 mount 될 때 함수 호출 + 의존값 업데이트 됬을 때
unmount : unmount 될 때 cleanup함수 호출 + 값이 바뀌기 직전에도 호출
: useEffect 안에서 사용하는 상태나, props가 있다면 deps에 넣어줘야한다.
그렇지않으면 useEffect에 등록한 함수가 실행 될 때 최신 props나 상태를 가르키지않는다.
( effect 안에 있으면서 다시 렌더링되어서 변경되는 모든것들을 deps에 넣어줘야한다.)
useEffect(() => {
console.log("user값이 설정됨");
console.log(user);
return () => {
console.log("user값이 바뀌기전...");
console.log(user);
};
}, [user]);
🔻 cleanup함수
setTimeout 타이머 썼으면 타이머해제 해줘야 한다.
예제에 'detail방문 시 2초후에 UI 사라지게 해라' 라고 했는데 2초전에 detail벗어나면 이상한일 일어날수도..
clearTimeout(타이머이름)
//return+함수 (컴포넌트 사라질 때 특정코드 실행)
useEffect(()=>{
let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
return ()=>{ clearTimeout(타이머) }
}, []);
🔻 Debounding / Throttiling
: 디바운싱과 쓰로틀링은 프로그램 기법 중 하나이다. 둘다 디바이스의 무리를 주지않기위해 사용된다.
debounce는 연이어 발생한 이벤트를 하나의 그룹으로 묶어서 처리한다.
throttle는 입력주기를 방해하지않고, 일정시간 동안의 입력을 모아서 한번씩 출력한다.
( user가 한글자씩 입력할 때 마다 데이터를 가지고오게되면, 성능면에서 비효율적이므로
사용자가 입력이 다끝났을 때 입력데이터를 가져오는것을 debouncing이라 한다.)
🔻 Destructuring
전체의 개체 대신 특정 속성을 종속성으로 전달한다.
// emailIsValid = emailState.isValid
const { isValid: emailIsValid } = emailState;
const { isValid: passwordIsValid } = passwordState;
useEffect(() => {
const identifier = setTimeout(() => {
console.log("checkign form validity!");
setFormIsValid(emailIsValid && passwordIsValid);
}, 500);
return () => {
console.log("cleanup");
clearTimeout(identifier);
};
}, [emailIsValid, passwordIsValid]);
ex) 페이지 이동 2초뒤에 컴포넌트 사라지게하기
// 1. UI가 보이고 안보이고의 상태를 state로 저장한다.
function Detail() {
let [재고, 재고변경] = useState(true);
// 2. state가 true일때만 UI가 보이게한다.
{재고 === true ? (
<div className="my-alert">
<p>재고가 얼마 남지 않았습니다</p>
</div>
) : null}
// useEffect import해준다.
import React, { useState, useEffect } from "react";
2. setTimeout이용해서 2초뒤에 false로 바꿔준다.
useEffect(() => {
let 타이머 = setTimeout(() => {
재고변경(false);
}, 2000);
};
> 이렇게 해주면 컴포넌트가 업데이트될 때도 저 useEffect가 실행된다.
update될 때는 useEffect() 실행하지 말아주세요. 라는 코드를 추가한다.
> 대괄호안에 state를 넣어서 '이 state가 변경 될 때만 업데이트로 치고 실행해라' 라는 명령 줄 수 있다.
콤마로 state여러개 추가할 수 있다.
// alert이라는 이름의 state가 변경될 때만 업데이트로 치고 실행해라.
useEffect(()=>{
let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
}, [ alert ]);
> 빈 대괄호를 추가해준다. (여기에는 state를 넣을 수 있다.)
조건을 안넣으면 컴포넌트 로드할때만 한번 실행한다.
useEffect(()=>{
let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
}, []);
useReducer
기본적으로 상태관리는 useState로하고 다음의 경우 reducer사용을 고려해본다.
- 관리해야 할 state가 많아질 때 ( state 여러개를 결합해야할 때 )
- 좀 더 복잡한 state updates 로직이 필요할 때 ( 다른 state에 의존하는 state를 update할 때 )
const [state, dispatch] = useReducer(reducer, initialArg, init);
reducer 기본 사용법
- 기본 reducer함수 생성
function reducer(state, action) {
switch (action.type) {
case "increment":
return state + 1;
case "decrement":
return state - 1;
default:
throw new Error("unhandled action");
}
}
- cosnt [기본값, 액션작동] = useReducer(만든reducer함수, 초기값)
function Counter () {
const [number, dispatch] = useReducer(reducer, 0)
}
- (state를 썼다면 setState로 조정하던 부분에서) dispatch type 지정
const onIncrease = () => {
dispatch({
type: "increment",
});
};
const onDecrease = () => {
dispatch({
type: "decrement",
});
};
useState VS useReducer
'Archive' 카테고리의 다른 글
[JS] this (0) | 2021.11.13 |
---|---|
[React] Ajax - axios (0) | 2021.10.25 |
[React] styled-components / SASS / CSS Module (0) | 2021.10.24 |
[React] Router (0) | 2021.10.24 |
[VSC] Prettier 적용방법 (0) | 2021.10.16 |