function Profile({userId}) {
const [user, setUser] = useState();
useEffect(() => {
fetchUser(userId).then(data => setUser(data));
}, [userId]);
}
⇒ 마운트 된 후 한번만 호출할 수 있도록 useEffect 의존성 배열에 빈배열 입력할 수 있지만 좋은 방법 ❌
⇒ userId가 바뀔때 렌더링 할 수 있도록 의존성 배열에 userId를 입력해 줘야함
💡 마운트 되었을 때만 실행되게 하려면 별도의 훅을 사용하는 것이 더 좋음
function Profile({ userId }) {
const [user, setUser] = useState();
useOnMounted(() => fetchUser(userId).then(data => setUser(data)))
}
💡 useEffect에서 async await함수를 사용하고 싶을 때
(async await함수는 Promise객체를 반환하기 때문에 useEffect에서 사용할 수 없음. useEffect는 함수만 반환 가능)
function Profile({ userId }) {
const [user, setUser] = useState();
useEffect(() => {
async function fetchAndSetUser(needDetail) {
const data = await fetchUser(userId, needDetail);
setUser(data);
}
fetchAndSetUser(false);
}, [userId]);
⇒ 위 코드에서 userId가 변경될 때만 useEffect함수가 렌더 되게 하려면 useCallback훅 사용
✔️ 의존성 배열은 되도록 사용하지 않는것이 좋음(∴ 관리하는데에 많은 시간과 노력 필요)
💡 여러 상태값을 참조하면서 값 변경할 때 → useReducer훅 사용
function Timer({ initialTotalSeconds }) {
const [state, dispatch] = useReducer(reducer, {
hour: initialTotalSeconds / 3600
minute: (initialTotalSeconds % 3600) / 60
second: initialTotalSeconds % 60
});
const { hour, minute, second } = state;
useEffect(() => {
const id = setInterval(dispatch, 1000);
return () => clearInterval(id);
});
//...
}
function reducer(state) {
const { hour, minute, second } = state;
if(second) {
return { ..state, second: second - 1 };
} else if(second) {
return { ..state, minute: minute - 1, second: 59 };
} else if(second) {
return { ..state, hour: hour - 1, minute: 59, second: 59 };
} else {
return state;
}
}
→ dispatch함수는 변경되지 않는 값이므로 의존성 배열에 입력하지 않아도 됨
💡 의존성 배열을 관리하는데에 마땅한 해결책이 생각나지 않는 경우 → useRef 훅 사용
function MyComponent({ onClick }) {
const onClickRef = useRef();
// concurrent mode를 위한 작성법
useEffect(() => {
onClickRef.current = onClick;
});
useEffect(() => {
window.addEventListener('click', () => {
onClickRef.current();
// ...
})
// ...
});
// ...
}
→ ref객체는 컴포넌트 안에서 직접 수정하면 안됨! (concurrent mode 때문)
리액트의 대부분의 연산 : 컴포넌트 함수의 실행 & 가상돔에서 발생
📍 React.memo사용시
memo로 감싼 컴포넌트에 두번째 인자로 비교함수를 넣어주면 그 값을 토대로 돔에 반영함
function MyComponent(props) {
// ...
}
function isEqual(prefProps, nextProps) {
// true 또는 false를 반환
}
React.memo(MyComponent, isEqual)
(두번째 인자로 비교 연산을 하지 않아도 되지만 넣어주면 렌더링 속도가 빨라짐)
❓ 이전 값과 현재값이 다르다는 것을 어떻게 비교
➡️ ===
연산자로 비교! (객체를 불변 객체로 관리)
prevProps.todos === nextProps.todos
💡 useCallback훅 사용
//...
const onChangeFruit = useCallback(fruit => {
setSelectedFruit(fruit);
sendLog({ type: 'fruit change', value: fruit });
}, []);
//...
<SelectFruit selected={selectedFruit} onchange={onchangeFruit} />
💡상태값의 레퍼런스가 변경되지 않기 때문
⇒ 상태값을 불변객체로 관리 해야함