React 게시판을 만들다가 조회수 구현을 하는데 게시글을 클릭할 때 마다 조회수가 두번씩 올랐다
왜 이러는지 이유를 찾아보겠다
React에서 useEffect 실행 방식
useEffect : 리액트 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook이다
1) useEffect가 처음 렌더링될 때만 실행하고 싶다
= 마운트 될 때만 실행된다
useEffect(() => {
//마운트 시 API 호출
axios.get('https://api.example.com/posts')
.then(response => setData(response.data))
.catch(error => console.error('데이터 로드 실패:', error));
}, []); // 빈 배열로 설정해 마운트 시 한번만 실행
useEffect의 두번째 매개변수로 전달되는 빈 배열 []은 의존성 배열이다
의존성 배열이 비어있으면 useEffect는 컴포넌트가 처음 마운트될 때만 실행되고 이후에는 실행되지 않는다
2) 특정 값이 업데이트 될 때만 호출하고 싶다
useEffect를 사용할 때 특정 값이 변경이 될 때만 호출하고 싶다면 의존성 배열에 해당 값을 포함하면 된다
import React, { useState, useEffect } from 'react';
const UpdateEffectExample = () => {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
//count 값이 변경될 때만 실행
useEffect(() => {
console.log('count가 변경되었습니다: ${count}');
}, [count]); //count를 의존성 배열에 추가
return (
<div>
<p>Count: {count}</p>
<button onClick{() => setCount(count +1)}> Increment Count</button>
<p>
Text: <input value={text} onchange={(e) => setText(e.target.value)} />
</p>
</div>
);
};
export default UpdateEffectExample;
useEffect는 count 값이 변경될 때만 실행된다
text 값이 변경되어도 useEffect는 실행되지 않는다(의존성 배열에 포함되지 않았기 때문)
count가 업데이트될 때마다 콘솔에 로그가 출력된다
3) 여러 값이 업데이트될 때 실행
import React, { useState, useEffect } from 'react';
const MultiDependencyExample = () => {
const [name, setName] = useState('');
const [age, setAge] = useState(0);
//name 또는 age가 변경될 때 실행
useEffect(() => {
console.log('Name 또는 Age가 변경되었습니다. Name: ${Name}', Age:${age}');
}, [name, age]); //name, age를 의존성 배열에 추가
return (
<div>
<p>
Name: <input value={name} onChange={(e) => setName(e.target.value)} />
</p>
<p>
Age: <input type="number" value={age} onChange={(e) => setAge(e.target.value)} />
</p>
</div>
};
};
export default MultiDependencyExample;
name 또는 age가 변경되면 useEffect 내부 코드가 실행된다
의존성 배열에 여러 값을 포함하면 해당 값들 중 하나라도 변경될 때 useEffect가 실행된다
4) 정리 :
useEffect는 기본적으로 렌더링되고 난 직후마다 실행되며, 두번째 파라미터 배열에 무엇을 넣느냐에 따라서 실행되는 조건이 달라진다
해결 방법 :
허무함
프로젝트의 index.js에서 해결할 수 있었다
<App />을 감싸고 있는 <React.StrictMode>태그를 주석 처리하니 간단히 해결되었다
그게 뭐냐면,,,
React의 StrictMode
리액트에서 제공하는 검사도구.
개발모드일 때 디버그를 통해, 이 태그로 감싸져있는 App 컴포넌트를 검사한다
안전하지 않은 생명 주기를 가진 컴포넌트, 권장되지 않은 부분, 배포 후 문제가 될 수 있는 부분들까지 미리 확인함
1) 'react-node-app'을 생성할 때 다음과 같이 생성했었는데
npx create-react-app react-node-app
create-react-app으로 앱을 만들면 해당 태그가 기본적으로 생성된다
2) useEffect를 두 번 실행하는 이유
① 부작용 감지 :
리액트의 useEffect는 컴포넌트가 마운트될 때 실행된다
개발 중에 <React.StrictMode>는 마운트 과정을 두 번 실행해 useEffect 내부에 정의된 부작용 코드가 안전하게 작동하는지 확인한다
② 클린업 테스트
useEffect에서 반환된 클린업 함수가 제대로 작동하는지 확인하기 위해 useEffect 실행 - 클린업 - 재실행 과정을 반복한다
③ 개발 중 실수 방지
개발자가 상태 업데이트나 부작용 코드를 잘못 작성하여 의도치 않은 동작을 유발하는 경우를 방지하기 위해 실행된다
<참고 : 리액트 공식 문서>
https://ko.legacy.reactjs.org/docs/strict-mode.html
'개발 기록 > front - react' 카테고리의 다른 글
[React] React 컴포넌트 생명주기, 생명주기 메소드 (0) | 2024.11.26 |
---|---|
[react] React 컴포넌트와 Props, State (1) | 2024.11.25 |
[JavaScript] 화살표 함수 = (arrow function) => {} (2) | 2024.11.20 |
[REACT] Failed to compile. Module not found : Can't resolve 'react-router-dom' (1) | 2024.11.04 |
[REACT] npm 패키지 설치 중 warn 이슈 - fsevents, requires a peer of typescript (0) | 2024.10.31 |