리액트 훅에서 useEffect는 컴포넌트가 렌더링될 때마다 특정 작업을 수행하도록 해주는 Hook이다.
class형 life cycle methods로 생각하면 componentDidMount + componentDidUpdate + componentWillUnmount 가 합쳐진 거라고 생각할 수 있다.
ko.reactjs.org/docs/hooks-effect.html
다양한 사용 케이스
참고 ↓
stackoverflow.com/questions/53070970/infinite-loop-in-useeffect#
1. 현재 / 부모 컴포넌트가 리렌더링 될 때마다 실행
useEffect(() => {
// don't know where it can be used :/
// 사용될 경우가 어디 있을까나?
})
- 기본적 형태로 함수를 호출하면 현재 / 부모 컴포넌트가 리렌더링될 때마다 실행됨!
- 어떤 사용법이 있을 진 잘 모르겠다
2. 현재 컴포넌트가 맨 처음 마운트 (렌더링) 될 때만 실행
useEffect(() => {
// do anything only one time if you pass empty array []
// keep in mind, that component will be rendered one time (with default values) before we get here
}, [] )
- useEffect 함수의 두 번째 파라미터로 [] 빈 배열을 넣어주면,
- 현재 컴포넌트가 맨 처음 마운트 (렌더링) 될 때만 실행된다.
- 이 때 중요한 점은, 컴포넌트가 마운트된 직후 useEffect 함수가 실행되기 때문에,
- useEffect 함수 실행 없이도 나머지 코드가 에러를 내지 않도록 설계하는 것이 필요하다.
============================================================
예시
- 내 프로젝트의 댓글 보여주기 컴포넌트의 경우,
- 댓글이 추가되거나 삭제될 때마다, 서버에 요청을 보내 댓글 목록을 새로 받아와야 했다.
- 서버 API가 요청 성공에 대한 응답으로 댓글 정보를 담은 data를 주지 않게 설계되었기 때문 (response.data)
- 만약 서버에서 response.data안에 내가 추가한 댓글 정보 (내용, postId, commentId - 이는 서버에서 할당)을 반환한다면,
- 이 데이터를 바탕으로 reducer에서 현재 상태를 업데이트하여
- 서버 요청 없이도 업데이트된 댓글 목록을 즉각 즉각 반영할 수 있다.
- 따라서 아래와 같이 설계.
- 서버 API가 요청 성공에 대한 응답으로 댓글 정보를 담은 data를 주지 않게 설계되었기 때문 (response.data)
- useEffect를 통해 현재 댓글들을 불러온다.
- 하지만 return () 부분에서, useEffect 사용 전에 currentComments를 이용해 컴포넌트들을 렌더링 하기 때문에
- currentComments가 업데이트되지 않은 상태 (null)이라면 에러가 난다.
- 때문에 currentComments가 있을 때에만 (null이 아닌 상태) 컴포넌트들을 렌더링 할 수 있도록
{ currentComments && ...
- 구문을 넣어주는 것이 필요했다.
- (나머지 액션 부분은 밑에서 설명!)
============================================================
3. 현재 컴포넌트가 맨 처음 마운트 (렌더링)될 때 + 특정 상태 값이 바뀔 때마다 실행
const [data, setData] = useState(false)
const [data2, setData2] = useState('default value for first render')
useEffect(() => {
// if you pass some variable, than component will rerender after component mount one time and second time if this(in my case data or data2) is changed
// if your data is object and you want to trigger this when property of object changed, clone object like this let clone = JSON.parse(JSON.stringify(data)), change it clone.prop = 2 and setData(clone).
// if you do like this 'data.prop=2' without cloning useEffect will not be triggered, because link to data object in momory doesn't changed, even if object changed (as i understand this)
}, [data, data2] )
- 위처럼 useEffect 두 번째 파라미터로 특정 값을 넣은 배열을 넣어준다면,
- 맨 처음 컴포넌트가 마운트 되었을 때
- 그리고 특정 값이 변할 때마다 useEffect가 실행된다.
============================================================
예시
- 따라서 위의 내 코드에서는 addCommentDone과 removeCommentDone 값이 변할 때마다 useEffect안의 코드가 실행
============================================================
4. 뒷정리 할 때
useEffect(() => {
//some code
return () -> {
//clean-up code
};
}, [data, data2] )
- 위처럼 함수 안에 return () => {} 함수를 넣어주면
- 뒷정리 함수로 여겨져
- 현재 컴포넌트가 언마운트될 때 return () => {} 안 구문이 실행된다.
useEffect 사용 예제 - 크소 플젝
지금 작업 중인 토이 프로젝트의 게시판 부분 (Post View)은 이렇게 구성되어 있다.
- 전체 게시글 보기 (PostView) 컴포넌트 안에
- 댓글 달기 (CommentForm) 컴포넌트 - 노란색 ,
- 댓글 보기 (CommentWrapper) 컴포넌트 - 갈색 - 가 있다.
- 게시글 나머지 부분 (게시글 제목, 내용, 작성자 등)은 GET /api/posts/{postId}에서,
- 댓글 부분은 GET /api/comments/{postId}에서 받아온다.
- 따라서 처음 댓글 보기 컴포넌트가 마운트되었을 때,
- 그리고 댓글이 추가될 때마다 (addPostDone상태가 리듀서 - 사가를 통해 바뀜)
- 또 댓글이 삭제될 때마다 (removePostDone상태가 리듀서 - 사가를 통해 바뀜!)
- useEffect 안의 코드가 실행되어 - GET_COMMENTS_REQUEST 액션이 디스패치되어
- 최신 댓글들을 불러오고 (currentComments),
- currentComments를 prop으로 받아들이는 CommentWrapper 부분이
- 리렌더링 되는 형태이다.
^_^
'개발 관련 개념들' 카테고리의 다른 글
[React.js] 리액트에서 무한 스크롤 구현 + 모바일 문제 해결 (0) | 2021.05.14 |
---|---|
[React.js] Each child in a list should have a unique "key" prop 계속 뜰 때 (0) | 2021.05.12 |
Github 리파지토리를 Re-fork하고 싶을 때!! (Upstream, Origin, Syncing) (0) | 2021.04.26 |
CSS가 이상하게 적용될 때, user agent stylesheet체크!! (0) | 2021.04.24 |
IntelliJ에서 Gradle기반 스프링 프로젝트 실행 - 오류 해결 로그 (0) | 2021.04.20 |
댓글