useEffect
란?
useEffect
Hook은 클래스형 컴포넌트에서 쓰이던 componentDidMount
와 componentDidUpdate
, componentWillUnmount
가 합쳐진 형태로 최초 렌더링 시 무조건 실행할 작업, 컴포넌트가 업데이트 될 때 작업, 컴포넌트가 언마운트(파괴, 제거)되었을 때 작업을 실행하게 해준다.
useEffect
사용 예시
useEffect
는 앞서 언급한 것처럼 최초 렌더링시, 컴포넌트 업데이트시, 컴포넌트 언마운트시 실행되는데 실행되는 내용은 useEffect
의 디폴트 파라미터인 콜백함수 내부에 들어가게 된다.
예를 들면
import React, { useState, useEffect } from "react";
export default function App() {
const [count, setCount] = useState(0);
const [appTitle, setAppTitle] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button
onClick={() => {
setCount(count + 1);
setAppTitle(count);
}}
>
Click me
</button>
<p>{appTitle}</p>
</div>
);
}
버튼을 클릭할 때마다 count
가 1씩 증가하게 되고 증가된 값은 appTitle
에 저장되어 화면에 나타난다.
단, appTitle
에 보이는 것은 count
의 값보다 1 작게 나타낼 것이다. count
와 appTitle
은 공통적으로 0부터 시작하지만 count
는 값이 증가하면서 리렌더링 되는 반면 appTitle
은 기존의 count
값을 갖고 있는 상태이기 때문에 count
값이 바뀌더라도 바로 렌더링 되지 않는다.
그래서 count
값이 바뀔 때마다 appTitle
의 값을 같은 값으로 변경해주기 위해서 useEffect
훅이 필요한 것이다.
import React, { useState, useEffect } from "react";
export default function App() {
const [count, setCount] = useState(0);
const [appTitle, setAppTitle] = useState(0);
useEffect(() => {
setAppTitle(count);
console.log(count);
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
<p>{appTitle}</p>
</div>
);
}
이렇게 바꿔주면 count
변수의 변화에 따라 appTitle
변수도 함께 변하게 된다. 다만 componentDidMount
와 componentDidUpdate
가 함께 작동하기 때문에 콘솔을 확인해보면 두번 실행됨을 알 수 있다.
그래서 dependency array를 두번째 파라미터로 추가하여 count
값이 변경될 때만 이를 감지하여 useEffect
내에 있는 함수를 호출하게 된다.
import React, { useState, useEffect } from "react";
export default function App() {
const [count, setCount] = useState(0);
const [appTitle, setAppTitle] = useState(0);
useEffect(() => {
setAppTitle(count);
console.log(count);
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
<p>{appTitle}</p>
</div>
);
}
주의할 점
만약 axios
모듈을 통해 비동기로 처리되어 List
형태의 데이터가 넘어온다고 가정할 때, List
내부 아이템이 바뀌는 경우 의존성 배열에 해당 리스트 변수를 넣어주면 무한루프를 돈다. useEffect
의 의존성 배열에는 반드시 state
만 존재해야 한다.
아래는 React Native 예시, false
로 세팅되어 있던 값을 버튼 클릭시 true
로 바꿔주고 useEffect
를 통해 false
로 컴포넌트를 언마운트하게 하여 배열 안에 있는 객체의 값이 바뀌었을 때만 리렌더링 할 수 있도록 한다. (무한루프 방지)
// ...
export default function App() => {
const [completed, setCompleted] = useState(false);
const [data, setData] = useState([]);
const Item = ({/*parameters...*/}) {
return (
{ // 백엔드로부터 넘어온 paymentDel(구매 취소여부 체커)이 0이면 구매완료 상태이므로 환불접수 버튼을 보여줌.
del === 0
? <TouchableOpacity
style={styles.refundBtn}
onPress={() => {
Alert.alert("환불접수", "환불을 접수하시겠습니까?", [
{text: "예", onPress: () => {
confirm = true;
console.log(`confirm: ${confirm}`);
onClickOrderCancel(confirm);
setCompleted(true)
}},
{text: "아니오"}
]);
}}
>
<Text style={{color: '#fff'}}>환불접수</Text>
</TouchableOpacity>
: <Text />
}
)
}
// ...
useEffect(() => {
//Alert.alert("useEffect start", "useEffect 실행")
const fetchData = async () => {
await axios.get(
"http://192.168.0.13:3000/payment/goodsPurchaseList",
{ params: { memberId: userId }
})
.then((res) => {
console.log(res.data);
setData(res.data);
})
.catch((err) => console.log(err));
}
fetchData();
return () => {
setCompleted(false)
//Alert.alert("useEffect", "useEffect 실행")
}
}, [completed]);
// ...
}
'Study > React' 카테고리의 다른 글
[React.js] 둥근 체크박스 만들기 (0) | 2022.04.26 |
---|---|
[React Native] Modal 사용하기 (0) | 2022.04.05 |
[React Native] 다른 페이지로 값 전달하기 (0) | 2022.03.23 |
[React Native] axios를 사용한 비동기 통신과 장면 전환 (1) | 2022.03.11 |
[React Native] axios를 사용하여 spring boot로 비동기 통신 하기 (0) | 2022.03.10 |