react강의 노트 | Byte Degree [3주차]
useEffect
- component가 화면에 나타나게 될 때, 사라지게 될 때 등
- 첫번째 파라미터에는 함수, 두번째 파라미터에는 deps
- return 함수는 뒷정리? 함수이며 , 업데이트 직전에 호출된다
mount - component가 나타나게 될 때
unmount - 삭제될때
useEffect(() => {
//comopnent가 나타남
console.log("컴포넌트가 화면에 나타남"); //
return () => {
//component가 사라짐
console.log("컴포넌트가 사라짐");
};
}, []);
- deps(의존 되는 값)가 비워져 있는 경우 - component가 처음 화면에 나타날 때만 실행된다.
- 사라지는 경우는 함수를 그냥 반환하면 된다.
- mount시 주로
props로 받은 값을 component state 값으로 설정하는 경우,
외부 API 요청하는 경우,
라이브러리 사용,
setInterval, setTimeout
- unmount시 주로
setInterval, setTimeout 제거할 때 - clearInterval, clearTimeout
라이브러리 인스턴스 제거
deps 배열 설정
//deps 배열 설정한 경우
//update 될때, 되기 전 모두 출력
useEffect(() => {
console.log("user 값이 업데이트됨");
console.log(user);
return () => {
console.log("user 값이 업데이트 전");
console.log(user);
};
}, [user]);
//user 값이 업데이트 전
//{id: 3, username: "ssdd", email: "ssdd@gmail.com", active: false}
//user 값이 업데이트 됨
//{id: 3, username: "ssdd", email: "ssdd@gmail.com", active: true}
---------------------------------------------
//deps 배열이 비워져 있는 경우
//component가 화면에 생길때, 제거될때 각각
useEffect(() => {
console.log("user 값이 설정");
console.log(user);
return () => {
console.log("user 값이 삭제");
console.log(user);
};
}, []);
//user 삭제
//{id: 3, username: "ssdd", email: "ssdd@gmail.com", active: false}
////user 설정
//{id: 4, username: "ssdd", email: "ssdd@gmail.com", active: false}
- 값이 바뀌기 전 값도 출력됨
- useEffect 사용시 해당 hook 내부에서 사용하고 있는 상태가 있다면 deps에 넣어줘야한다. (나중에 오류가 생길 수 있음)
useMemo
- 성능을 최적화해야하는 함수에서 사용
function countActiveUsers(users) {
console.log("활성 사용자 수를 세는 중...");
return users.filter((user) => user.active).length;
}
//active된 user count
const count = countActiveUsers(users);
//onChange마다 console이 계속 찍힌다.-> 불필요
----------------- ↓ ------------------
//useMemo hook사용시
function countActiveUsers(users) {
console.log("활성 사용자 수를 세는 중...");
return users.filter((user) => user.active).length;
}
//active된 user count
const count = useMemo(() => countActiveUsers(users), [users]);
//deps에 users를 넣으면 users가 변할만 함수가 실행된다.
- 위처럼 코드 작성시, user.active가 변화될 때만 console이 찍히지 않고, onChange가 일어날때마다 활성화되어 불피요한 출력을 하게 된다.
-> 특정값이 바뀌었을 때만 특정 연산을 하게 되고 원하는 값이 바뀌지 않은 경우 이전에 만들어뒀던 값을 재사용한다.
- 첫번쨰 파라미터는 함수. 두번째 파라미터는 deps
- deps에 들어온 요소가 변할 때만 함수가 실행된다.
useCallback
- 최적화, 함수 재사용시
- deps에 들어오는 요소가 바뀔때만 해당 함수가 실행, 그렇지 않으면 기존함수 재사용되는 hook
- deps에 참조하고 있는 요소 넣기
//리렌더링 되는 함수 useCallback hook으로 감싸서 최적화 하기
const onRemove = useCallback(
(id) => {
setUsers(users.filter((user) => user.id !== id));
},
[users] //참조할
);
const onToggle = useCallback(
(id) => {
setUsers(
users.map(
(user) => (user.id === id ? { ...user, active: !user.active } : user)
//클릭 한 기존 객체 user를 가져와서 user.active의 상태를 반대로 변화 (true, false)
//클릭 하지 않은 user은 그대로
)
);
},
[users]
);
- 어떤 함수가 리렌더링 되는지 알 수 있는 'react devtools' 사용하기
'react devtools' 의 ' Highlight updates when components render.'를 체크하여 렌더링 되고 있는 component 확인하기
- 간단하게 console로도 확인가능
↓ + 더 최적화하기 deps 사용 주의
+) Read.memo
- component 리렌더링 방지 (최적화)
export default React.memo(CreateUser);
//React.memo - props가 바뀌었을 때만 리렌더링 해줌(최적화)
const User = React.memo(function User({~}){
})
//배열 삭제
const onRemove = useCallback((id) => {
setUsers((users) => users.filter((user) => user.id !== id));
}, []);
//deps 배열을 비우고 (기존 users 참조하지말기) useState의 함수형 업데이트를 하기
//-> setUsers에서 최신 users를 조회하게 하기
//toggle
const onToggle = useCallback((id) => {
setUsers((users) =>
users.map(
(user) => (user.id === id ? { ...user, active: !user.active } : user)
//클릭 한 기존 객체 user를 가져와서 user.active의 상태를 반대로 변화 (true, false)
//클릭 하지 않은 user은 그대로
)
);
}, []);
//deps 배열을 비우고 (기존 users 참조하지말기) useState의 함수형 업데이트를 하기
//-> setUsers에서 최신 users를 조회하게 하기
- 두번째 파라미터에 propsAreEqual 사용할 수 있다.
- 연산된 값을 재사용하기 위해서는 useMemo
- 특정함수를 재사용하기 위해서는 useCallback
- component 렌더링된 결과물을 재사용하기 위해서는 React.Memo
=> 성능 최적화 할 수 있겠다, 필요하겠다 싶을 때 사용하기. 그렇지 않으면 코드만 더 길어짐
useReducer
- useState 처럼 상태를 업데이트 할 수 있는 hook
- 차이점
useState - 설정하고 싶은 다음 상태를 직접 지정해주는 방식 (setValue(5))
useReducer - action이라는 객체를 기반으로 상태를 업데이트 한다. (dispatch({type: 'INCREMENT'}))
- 상태 업데이트 로직을 컴포넌트 밖으로 분리 가능
(action = 업데이트할때 참조한는 객체, dispatch = action을 발생시키는 함수)
- reducer : 상태를 업데이트하는 함수
- 첫번째 파라미터 reducer함수, 두번째 기본값
//useReducer
import { render } from "@testing-library/react";
import React, { useReducer } from "react";
//reducer함수 생성
function reducer(state, action) {
switch (action.type) {
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1;
default:
return state;
//throw new Error('Unhandled action'); 둘 다 무관
}
}
function Counter() {
const [number, dispatch] = useReducer(reducer, 0); //첫번째 reducer함수, 두번쨰 초기값
const onIncrease = () => {
dispatch({
type: "INCREMENT",
});
};
const onDecrease = () => {
dispatch({
type: "DECREMENT",
});
};
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
+ App에서 useReducer 사용하기
- app에서 useState로 구현한 것을 useReducer로 구현해보기
- app component에서 사용할 초기상태를 component 밖에서 선언해주기
언제 사용하면 될까?
간단 - useState
복잡 - useReducer
'React' 카테고리의 다른 글
[React 강의 노트(5)] class형 component (0) | 2020.12.16 |
---|---|
[React 강의 노트(4)] 커스텀 Hook 만들기, context API, Immer (0) | 2020.12.15 |
[React 강의 노트(2)] CRUD (0) | 2020.12.10 |
[React 강의 노트(1)] React (0) | 2020.12.09 |
React에서 'onClick' Event 실행해보기 (0) | 2020.12.09 |