- 이전에는 컴포넌트의 상태를 관리하거나 생명 주기에 따라 특정 작업을 수행하려면 클래스형 컴포넌트를 사용해야 했음.
- 하지만 Hooks를 이용할 수 있게 되면서 함수형 컴포넌트에서도 상태를 관리할 수 있게 되었고 컴포넌트의 생명 주기에 맞춰 특정 작업을 수행할 수 있게 됨.
6.1 useState
const [state, setState] = useState(initialState);
- return : [변수, 세터 함수]
- 세터 함수 : 변수를 수정할 수 있는 함수
- useState 함수는 관리해야 하는 상태의 수만큼 여러 번 사용할 수 있음.
- 상태를 관리하는 변수는 반드시 세터 함수를 이용해 값을 변경해야 함 -> 상태가 변경되면 컴포넌트가 변경된 내용을 반영하여 재렌더링 됨.
세터 함수
- 세터 함수에 변경될 상태의 값을 전달 ( setState(newState) )
- 세터 함수의 파라미터에 함수를 전달 ( setState(prevState => {}) )
- 세터 함수는 비동기로 동작하기 때문에 세터 함수를 호출해도 바로 상태가 변경되지 않는 문제점이 있음.
-> 상태에 대해 여러 업데이트가 함께 발생할 경우, 2번 방법으로 함수를 인자로 전달하면 문제 해결
6.2 useEffect
useEffect(() => {}, []);
- 1번째 파라미터 : 함수 - 조건을 만족할 때마다 호출
- 2번째 파라미터 : (의존성) 배열 - 함수가 호출되는 조건 설정
- 의존성 배열 X : 컴포넌트가 렌더링될 때마다 호출 / cleanup 함수도 같이 실행
- [변수] : 그 변수의 상태가 변경되었을 때만 호출 / cleanup 함수가 실행된 뒤 새로운 Effect 실행
- [ ] : 컴포넌트가 처음 생성(mount)되었을 때 1번만 호출 / cleanup 함수는 언마운트(unmount)될 때 실행
- 상태의 값을 변경하는 세터 함수가 비동기로 동작하므로 상태의 값이 변경되면 실행할 함수를 useEffect로 정의해야 함.
6.3 useRef
- 특정 컴포넌트를 선택해서 포커스를 설정하고 싶은 경우 등에 사용
const ref = useRef(initialValue);
// 예시 : TextInput 컴포넌트 포커스 옮기기
const Form = () => {
const refName = useRef(null);
const refEmail = useRef(null);
...
useEffect(() => {
refName.current.focus();
}, []);
...
return (
...
<StyledTextInput
ref={refName}
onSubmitEditing={() => refEmail.current.focus()}
...
/>
<StyledTextInput
ref={refEmail}
...
/>
);
};
주의
- 컴포넌트의 ref로 지정하면 생성된 변수에 값이 저장되는 것이 아니라 변수의 .current property에 해당 값을 담음.
- useRef의 내용이 변경되어도 재렌더링 되지 않음.
6.4 useMemo
- 동일한 연산의 반복 수행을 제거해서 성능 최적화
useMemo(() => {}, []);
- 1번째 파라미터 : 함수 - 조건을 만족할 때마다 호출
- 2번째 파라미터 : (의존성) 배열 - 함수가 호출되는 조건 설정
// 예시 : 배열을 순회하며 요소(문자열)의 길이 재기
const list = ['JavaScript', 'Expo', 'React Native'];
const getLength = text => text.length;
let idx = 0;
const Length = () => {
const [text, setText] = useState(list[0]);
const onPress = () => {
setLength(getLength(text));
++idx;
if (idx < list.length) setText(list[idx]);
};
const length = useMemo(() => getLength(text), [text]);
return (
<>
<Text>text : {text}</Text>
<Text>length : {length}</Text>
<Button title='Get Length' onPress={onPress} />
</>
);
};
6.5 커스텀 Hooks 만들기
목표 : 특정 API에 GET 요청을 보내고 응답을 받는 함수 (Fetch를 이용하여 useFetch 만들기)
- React Native는 네트워크 통신을 위해 Fetch와 XMLHttpRequest를 제공하고, 추가적으로 WebSocket도 지원함.
// 예시 : useFetch
// src/hooks/useFetch.js
export const useFetch = url => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [inProgress, setInProgress] = useState(false);
useEffect(() => {
const fetchData = async () => {
try {
setInProgress(true);
const res = await fetch(url);
const result = await res.json();
if (res.ok) {
setData(result);
setError(null);
} else {
throw result;
}
} catch (e) {
setError(error);
} finally {
setInProgress(false);
}
};
fetchData();
}, []);
return { data, error, inProgress };
};
// src/components/Dog.js
const URL= '~~';
const Dog = () => {
const { data, error, inProgress } = useFetch(URL);
return (
<>
{inProgress && (
<Text>The API request is in progress.</Text>
)}
<Image source={data?.message ? { uri: data.message } : null} />
<Text>{error?.message}<Text>
</>
);
};
본문에서 설명하는 내용과 사용한 이미지는 책 '처음 배우는 리액트 네이티브'를 참고하였습니다.
'처음 배우는 리액트 네이티브' 카테고리의 다른 글
8장 내비게이션 (0) | 2025.01.28 |
---|---|
7장 Context API (1) | 2025.01.23 |
5장 할 일 관리 애플리케이션 (0) | 2025.01.22 |
추가 : React-Native styled-components 설치 오류 해결 방법 (0) | 2025.01.19 |
4장 스타일링 (0) | 2025.01.16 |