일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- JavaScript
- 엘리스 ai 트랙
- 코드스테이츠
- 날씨 웹 만들기
- HTML
- 엘리스
- 자바스크립트 날씨 웹 만들기
- 리트코드
- 자바스크립트 reduce()
- 프론트개발
- 프론트개발공부
- leetcode
- 개발공부
- 간단한 날씨 웹 만들기
- 자바스크립트 날씨
- [파이썬 실습] 중급 문제
- 엘리스 AI 트랙 5기
- 자바스크립트 split()
- 삼항연산자
- 부트캠프
- 개발일기
- 코딩부트캠프
- [파이썬 실습] 심화 문제
- 프로그래머스
- [파이썬 실습] 기초 문제
- 자바스크립트
- [AI 5기] 연습 문제집
- 자바스크립트 sort()
- reactnativecli
- RN 프로젝트
- Today
- Total
개발조각
[React-native CLI] RN에서 useCallback 사용 (useEffect 의존성 배열 오류 발생 해결) 본문
[React-native CLI] RN에서 useCallback 사용 (useEffect 의존성 배열 오류 발생 해결)
개발조각 2024. 3. 15. 17:21이번에 프로젝트 작업을 하면서 useCallback을 사용하게 되었습니다.
useCallback이란
useCallback hook은 메모이제이션된 콜백 함수를 생성하는 데 사용됩니다.
일반적으로 컴포넌트에서 함수를 정의할 때마다 해당 함수는 새로운 참조를 갖게 되고, 이는 매번 렌더링 될 때마다 새로운 함수가 생성하게 됩니다. 그러므로 이러한 함수 생성은 성능에 영향을 줄 수 있습니다.
useCallback훅은 이러한 문제를 해결하기 위해 사용되며, useCallback으로 감싼 함수는 해당 ㅎ마수의 의존성 배열이 변경되지 않는 한 이전에 사용된 함수를 재사용합니다.
이는 동일한 함수를 여러번 생성하는 것을 방지하고 성능을 향상할 수 있습니다.
사용 예시
import React, { useCallback } from 'react';
const MyComponent = () => {
const handleClick = useCallback(() => {
console.log('Button clicked!');
}, []); // 의존성 배열이 비어있으므로 이 콜백 함수는 변하지 않음
return <button onClick={handleClick}>Click me</button>;
};
여기에서는 handleClick 함수는 빈 의존성 배열을 갖고 있기 때문에 컴포넌트가 렌더링 될 때마다 같은 함수가 재사용됩니다.
만약 의존성 배열에 상태나 props가 있다면, 해당 상태나 prop가 변경될 때만 새로운 함수가 생성됩니다.
useCallback은 성능 최적화를 위해 콜백 함수를 메모이제이션할 때 사용되며, 불필요한 함수 생성을 방지하여 애플리케이션의 성능을 향상할 수 있습니다.
작성한 코드
selectDate의 값이 바뀔때마다 ReadDB에 바뀐 selectDate의 값을 넣어주는 코드
const [selectDate, setSelectDate] = useState(date); // 선택한 날짜
// 선택한 날짜가 바뀌면 useReducer의 기본값 바뀌게 하기
useEffect(() => {
readDB();
}, [selectDate]);
const realm = useRef<Realm>();
// realmDB 열기, 닫기
useEffect(() => {
openLocalDB();
return () => {
realm.current?.close();
console.log('realmDB 닫기!');
};
}, []);
const openLocalDB = async () => {
realm.current = await Realm.open({schema: [RecordSchema]});
console.log('realmDB 열기!');
// readAllDB();
readDB();
};
const readDB = () => {
const data = realm.current
?.objects('Record')
.filtered(`date = '${selectDate}'`);
if (data?.length) {
console.log(`${selectDate} 데이터:`, data);
} else {
console.log(`${selectDate}데이터가 없습니다.`, data);
}
};
이렇게 작성하면 아래와 같은 오류 발생
오류 발생 및 해결하기
1차 문제 : selectDate에서 오류 발생
// 선택한 날짜가 바뀌면 useReducer의 기본값 바뀌게 하기
useEffect(() => {
readDB();
}, [selectDate]); // selectDate에 오류 발생
해석 : React Hook use Effect에 'readDB'라는 누락된 종속성이 있습니다. 종속성 배열을 포함하거나 제거하십시오.
이러한 오류가 발생한 이유
useEffect hook은 종속성 배열에 등록된 값들이 변경될 때만 실행됩니다.
현재 코드에서는 readDB함수가 useEffect의 콜백 내에서 호출되지만 종속성 배열에 등록되지 않았습니다.
(종속성 배열이란 useEffect에서 두 번째 인자 []를 의미 )
그래서 readDB함수가 변경되더라도 useEffect는 감지하지 못하고 이전에 생성된 readDB함수를 계속 사용하게 됩니다.
따라서 useEffect가 readDB 함수의 변경을 감지하고 새로운 readDB 함수를 사용하도록 하려면 readDBfmf useEeffect의 종속성 배열에 등록해야 됩니다. 이렇게 하면 selectDate가 변경될 때마다 새로운 readDB함수가 생성되어 useEffect가 이를 감지하고 실행하게 됩니다.
해결방안 결론 : useEffect를 selectDate와 readDB에 종속되도록 변경해 주어야 됨
1차 문제 해결방안 : useEffect를 selectDate와 readDB에 종속되도록 변경
// 선택한 날짜가 바뀌면 useReducer의 기본값 바뀌게 하기
useEffect(() => {
readDB();
}, [readDB, selectDate]);
하지만 또다른 오류 발생
2차 문제 : readDB() 오류
// 선택한 날짜가 바뀌면 useReducer의 기본값 바뀌게 하기
useEffect(() => {
readDB();
}, [readDB, selectDate]);
이렇게 변경되면 아래와 같은 오류 발생
해석 : readDB' 기능은 useEffectHook(47행)의 종속성을 모든 렌더에서 변경합니다. 이를 수정하려면 'readDB'의 정의를 자체 useCallback() Hook으로 감싸십시오.
이러한 오류가 발생한 이유
useEffect hook은 종속성 배열에 등록된 값들이 변경될 때만 실행됩니다.
여기서 readDB 함수가 새로운 레퍼런스로 생성되므로 매번 변경된 것으로 간주되어 useEffect가 매번 실행하게 되서 오류가 발생합니다.
useEffect가 매번 실행되는 것을 방지하기 위해서는 useCallback() hook을 사용해주어야 됩니다.
왜 useCallback() Hook를 사용해야 되는 이유는
useCallback을 사용하면 readDB함수가 컴포넌트가 리렌더링될 때마다 새로 생성되지 않도록 할 수 있습니다.
그래서 readDB 함수를 useCallback으로 감싸서 컴호넌트가 리렌더링 될 때마다 새로 생성되는 것을 방지합니다.
2차 문제 해결방안 : useCallback() Hook 사용하고, 종속성 배열에 selectDate 넣기
const readDB = useCallback(() => {
const data = realm.current
?.objects('Record')
.filtered(`date = '${selectDate}'`);
if (data?.length) {
console.log(`${selectDate} 데이터:`, data);
} else {
console.log(`${selectDate}데이터가 없습니다.`, data);
}
}, [selectDate]);
이제 readDB 함수는 selectDate가 변경될 때만 새로 생성되고, useEffect는 readDB함수나 selectDate가 변경될 때만 실행됩니다.
오류 발생 1의 해결된 코드
이렇게 코드를 작성하면 오류가 발생했는데
// 선택한 날짜가 바뀌면 useReducer의 기본값 바뀌게 하기
useEffect(() => {
readDB();
}, [readDB, selectDate]);
const readDB = useCallback(() => {
const data = realm.current
?.objects('Record')
.filtered(`date = '${selectDate}'`);
if (data?.length) {
console.log(`${selectDate} 데이터:`, data);
} else {
console.log(`${selectDate}데이터가 없습니다.`, data);
}
}, [selectDate]);
이러한 오류가 발생한 이유는 useEffect에서는 종속성 배열에 함수를 추가할 때 해당 함수는 반드시 이전에 선언되어야 합니다.
(즉, 함수가 호출되기 전에 해당 함수를 정의 해야 됩니다.)
readDB와 useEffect()위치를 바꿔주었습니다.
const readDB = useCallback(() => {
const data = realm.current
?.objects('Record')
.filtered(`date = '${selectDate}'`);
if (data?.length) {
console.log(`${selectDate} 데이터:`, data);
} else {
console.log(`${selectDate}데이터가 없습니다.`, data);
}
}, [selectDate]);
// 선택한 날짜가 바뀌면 useReducer의 기본값 바뀌게 하기
useEffect(() => {
readDB();
}, [readDB, selectDate]);
전체코드
const [selectDate, setSelectDate] = useState(date); // 선택한 날짜
// const [state, dispatch] = useReducer(reducer, )
const realm = useRef<Realm>();
// selectDate에 해당하는 데이터 있는지 체크 및 가져오기
const readDB = useCallback(() => {
const selectDateData = realm.current
?.objects('Record')
.filtered(`date = '${selectDate}'`)[0];
if (selectDateData) {
console.log(`${selectDate} 데이터:`, selectDateData);
} else {
console.log(`${selectDate}데이터가 없습니다.`);
}
}, [selectDate]);
// 선택한 날짜가 바뀌면 useReducer의 기본값 바뀌게 하기
useEffect(() => {
readDB();
}, [readDB, selectDate]);
const openLocalDB = async () => {
realm.current = await Realm.open({schema: [RecordSchema]});
console.log('realmDB 열기!');
readDB();
};
// realmDB 열기, 닫기
useEffect(() => {
openLocalDB();
return () => {
realm.current?.close();
console.log('realmDB 닫기!');
};
}, []);
'React-Native > [프로젝트] 택시 운행관리 기록장' 카테고리의 다른 글
[React-native CLI] RN 기록화면 구현하기 1부 (선택한 날짜에 따라 Creact, Update하기) (0) | 2024.03.18 |
---|---|
[React-native CLI] RN에서 react-native-calendars 사용하기 (0) | 2024.03.18 |
[React-native CLI] Modal 구현하기, 모달 커스텀 (0) | 2024.03.14 |
[React-native CLI] day.js를 이용한 달력 이동 (0) | 2024.03.14 |
[React-native CLI] RN 뒤로가기 (0) | 2024.03.13 |