Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- 백준
- 깃 터미널 연동
- 문자열
- 백준 4358번
- 백준 4949번
- 머신러닝
- HTTP
- 데베
- SQL
- React Native
- 팀플회고
- 깃허브 로그인
- 모두의네트워크
- 모두를위한딥러닝
- 깃 연동
- 네트워크
- 리액트 네이티브 프로젝트 생성
- 딥러닝
- 백준 4358 자바
- 리액트 네이티브
- 지네릭스
- 자바
- 정리
- 백준 5525번
- 모두의 네트워크
- 스터디
- 데이터베이스
- 깃허브 토큰 인증
- 모두를 위한 딥러닝
- 리액트 네이티브 시작하기
Archives
- Today
- Total
솜이의 데브로그
[React Native] Hooks 본문
Reference : 처음 배우는 리액트 네이티브
Hooks
리액트 네이티브 16.8 버전에서 새롭게 추가된 기능이다.
컴퓨넌트의 상태를 관리하거나 생명 주기에 따라 특정 작업을 수행하려면 클래스형 컴포넌트를 사용해야 했다.
하지만 Hooks를 이용할 수 있게 되면서 함수형 컴포넌트에서도 상태를 관리할 수 있게 되었다.
useState
- useState 함수를 호출하면 변수와 그 변수를 수정할 수 있는 세터 함수를 배열로 반환한다.
- 파라미터로 전달한 값을 초깃값으로 갖는 상태 변수와 그 변수를 수정할 수 있는 세터 함수를 배열로 반환.
- 상태를 관리하는 변수는 반드시 세터 함수를 이용해 값을 변경해야 하고, 상태가 변경되면 컴포넌트가 변경된 내용을 반영하여 다시 렌더링한다.
src/components/Counter.js
- 숫자를 나타내는 count 생성
- Button 컴포넌트를 이용해 클릭될 때마다 세터함수를 이용해 상태를 변경
세터 함수
- 세터 함수의 파라미터에 함수를 전달 할 수 있다.
- 세터 함수는 비동기로 동작하기 때문에 상태 변경이 여러 번 일어날 경우 상태가 변경되기 전에 또 다시 상태에 대한 업데이트가 실행된다.
- 상태에 대해 여러 업데이트가 함께 발생할 경우, 세터 함수에 함수를 인자로 전달하여 이전 상태값을 이용한다.
- 이전 상태의 값에 의존하여 상태를 변경할 경우 세터함수에 함수를 인자로 전달한다.
import React, { useState } from "react";
import styled from 'styled-components/native';
import Button from "./Button";
const StyledText = styled.Text`
font-size: 24px;
margin: 10px;
`;
const Counter = () => {
const [count, setCount] = useState(0);
return(
<>
<StyledText>count: {count}</StyledText>
<Button
title="+"
onPress={()=> {
setCount(prevCount => prevCount+1);
setCount(prevCount => prevCount+1);
}}
/>
<Button
title="-"
onPress={()=>{
setCount(count-1);
}}
/>
</>
);
};
export default Counter;
useEffect
- useEffect의 첫 번째 파라미터로 전달된 함수는 조건을 만족할 때마다 호출되고, 두 번째 파라미터로 전달되는 배열을 이용해 함수가 호출되는 조건을 설정할 수 있다.
- 두번째 파라미터에 값을 전달하지 않으면 첫번째 파라미터로 전달된 함수는 컴포넌트가 렌더링 될 때마다 호출된다.
- TextInput 컴포넌트를 이용해서 이메일과 이름을 입력받는 컴포넌트를 만들고, useEffect를 사용해서 컴포넌트와 다시 렌더링 될 때마다 name과 email을 출력하도록 한다.
특정 조건에서 실행하기
- useEffect에 설정한 함수를 특정 상태가 변경될 때만 호출하고 싶은 경우, 두번째 파라미터에 해당 상태를 관리하는 변수를 배열로 전달한다.
- 세터함수가 비동기로 작동하므로 상태의 값이 변경되면 실행할 함수를 useEffect를 이용해서 정의한다.
- 두번째 파라미터로 [email] 을 전달하면 email의 상태가 변경되었을 때만 함수가 실행되도록 한다.
- 두번째 파라미터에 빈 배열을 전달하면 컴포넌트가 처음 렌더링 될 때만 함수가 호출되도록 작성할 수 있다.
src/components/Form.js
import React, { useState, useEffect } from "react";
import styled from "styled-components/native";
const StyledTextInput = styled.TextInput.attrs({
autoCapitalized: 'none',
autoCorrect: false,
})`
border: 1px solid #757575;
padding: 10px;
margin: 10px 0;
width: 200px;
font-size: 20px;
`;
const StyledText = styled.Text`
font-size: 24px;
margin: 10px;
`;
const Form = () => {
const[name, setName] = useState('');
const[email, setEmail] = useState('');
useEffect(()=> {
console.log(`\n======Form Component Mount=======\n`);
return() => console.log('\n========Form Component Unmount========\n');
}, []);
return(
<>
<StyledText>Name: {name}</StyledText>
<StyledText>Email: {email}</StyledText>
<StyledTextInput
value={name}
onChangeText={text => setName(text)}
placeholder="name"
/>
<StyledTextInput
value={email}
onChangeText={text => setEmail(text)}
placeholder="email"
/>
</>
);
};
export default Form;
useRef
- 리액트 네이티브에서 특정 컴포넌트로 포커스를 설정하고 싶은 경우 해당 컴포넌트를 선택할 수 있다.
- 이 때 Hook 함수 중 useRef를 사용한다.
- 컴포넌트의 ref로 지정하면 생성된 변수에 값이 저장되는 것이 아니라 변수의 .current 프로퍼티에 해당 값을 담는다.
- useState를 이용하여 생성된 상태와 달리 useRef의 내용이 변경돼도 컴포넌트는 다시 렌더링 되지 않는다.
- useRef 함수를 이용하여 refName과 refEmail 을 생성해 각각 이름과 이메일을 입력받는 TextInput 컴포넌트의 ref로 설정하고, 키보드의 완료 버튼을 각각 next와 done으로 변경한다.
- next 버튼을 누르면 이메일을 입력받는 컴포넌트로 포커스가 이동하도록 작성한다.
useMemo
- 동일한 연산의 반복 수행을 제거해서 성능을 최적화하는데 사용한다.
- 첫 번째 파라미터에 함수를 전달하고, 두 번째 파라미터에는 함수 실행 조건을 배열로 전달한다.
src/components/Length.js
import React, { useState, useMemo } from "react";
import styled from 'styled-components/native';
import Button from "./Button";
const StyledText = styled.Text`
font-size: 24px;
`;
const getLength = text => {
console.log(`Target Text : ${text}`);
return text.length;
};
const list = ['JavaScript', 'Expo', 'Expo', 'React Native'];
let idx = 0;
const Length = () => {
const[text, setText] = useState(list[0]);
const _onPress = () =>{
++idx;
if (idx<list.length) setText(list[idx]);
};
const length = useMemo(()=> getLength(text), [text]);
return(
<>
<StyledText>Text: {text}</StyledText>
<StyledText>Length: {length}</StyledText>
<Button title="Get Length" onPress={_onPress} />
</>
);
};
export default Length;
- 버튼을 클릭할 때마다 문자열의 길이를 구하는 컴포넌트
- useMemo를 사용하여 문자열의 변화가 없는 경우 반복하지 않도록 한다.
커스텀 Hooks 만들기
- 특정 API에 GET 요청을 보내고 응답을 받는 함수를 만들어보자.
- 리액트 네이티브에서는 네트워크 통신을 위해 Fetch와 XMLHttpRequest를 제공하고, WebSocket도 지원한다.
- Fetch를 이용하여 useFetch라는 이름의 Hook을 만든다.
src/hooks/useFetch.js
import { useState, useEffect } from "react";
export const useFecth = url => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [inProgress, setInProgress] = useState(false);
useEffect(async () => {
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(error){
setError(error);
} finally{
setInProgress(false);
}
};
fetchData();
}, []);
return {data, error, inProgress};
};
- 전달받은 API의 주소로 요청을 보내고 결과의 성공 여부에 따라 data 혹은 error에 담아서 반환하는 useFecth를 작성한다.
- 비동기 함수를 이용해야 하는 상황에서는 useEffect에 전달되는 함수 내부에 비동기 함수를 정의하고 사용해야한다.
- API의 진행 상태를 관리하는 inProgress를 만들고, API 요청 시작 전과 완료 후 상태를 변경해서 useFetch의 API 진행상태를 확인하도록 한다.
src/components/Dog.js
import React from "react";
import styled from "styled-components/native";
import { useFecth } from "../hooks/useFetch";
const StyledImage = styled.Image`
background-color: #7f8c8d;
width: 300px;
height: 300px;
`;
const ErrorMessage = styled.Text`
font-size: 18px;
color: #e74c3c;
`;
const LoadingMessage = styled.Text`
font-size: 18px;
color: #2ecc71;
`;
const URL = 'https://dog.ceo/api/breeds/image/random';
const Dog = () => {
const {data, error, inProgress} = useFecth(URL);
return(
<>
{inProgress && (
<LoadingMessage>The API request is in progress</LoadingMessage>
)}
<StyledImage source={data?.message ? { uri: data.message }: null} />
<ErrorMessage>{error?.message}</ErrorMessage>
</>
);
};
export default Dog;
- Dogs API를 이용해 무작위로 강아지 사진을 받아오는 컴포넌트를 생성한다.
Hooks는 클래스형 컴포넌트를 사용하지 않아도 함수형 컴포넌트에서 상태를 관리하고 다양한 상황에 맞춰 작업할 수 있게 해주는 기능이다.
함수형 컴포넌트는 이를 이용해 클래스형 컴포넌트에서 가능했던 거의 대부분의 기능을 구현할 수 있다.
'dev > React native' 카테고리의 다른 글
[React Native] Navigation (0) | 2021.11.21 |
---|---|
[React Native] Context API (0) | 2021.11.14 |
[React Native] 할 일 관리 애플리케이션(2) (0) | 2021.11.06 |
[React Native] 할 일 관리 애플리케이션(1) (0) | 2021.11.05 |
[React Native] 스타일링 (0) | 2021.10.16 |