728x90
React 비동기 - 사진 출력하기
온라인 코딩툴 사이트 : https://snack.expo.dev/
코드전체 : https://snack.expo.dev/@rebornborn/happy-almond?platform=ios
Dog.js
import styled from 'styled-components';
import { useFetch } from './useFetch'
// ` ESC키 하단에 있는 EC6기반의 변수할당하는 문법
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;
`;
//spring boot의 이미지 파일 업로드하면 그 주소값을 찾는 URL을 호출
const URL = 'https://dog.ceo/api/breeds/image/random';
//매개변수가 있으므로 메서드로 인식
const Dog = () => {
const { data, error, inProgress } = useFetch(URL);
return (
// <View>
<>
{inProgress && (
<LoadingMessage> API request ing </LoadingMessage>
)}
<StyledImage source={data?.message ? {uri: data.message} : null}>
</StyledImage>
<ErrorMessage>{error?.message}</ErrorMessage>
</>
);
};
export default Dog;
useFetch 함수를 실행함으로 비동기 통신 시작
현재 페이지는 동일하나, 특정 영역만 서버에 호출하여 response를 기다림
data useFetch를 통해 데이터 request 호출을 진행하여 정상실행 일 경우
리턴받는 데이터 값
error 정상실행이 안되서 실패할 경우 메세지
inProgress useFetch를 통해 데이터 request 호출을 진행하였으나, 에러 또는 성공 유무를 확인 할 수 없을 때
<>
inProgress 변수는 원래는 false 이기 때문에 && 구문으로
뒤에 값이 true가 오든 false가 오든 모두 false 인 전제조건에 시작
inProgress 는 비동기 통신이 모두 완료되는 시점까지 loadingMessage 함수가 출력되고
서버 통신(비동기) 완료될 때에 API request ing라는 문구가 사라짐
{inProgress && (<LoadingMessage> API request ing </LoadingMessage> )}
data는 useFetch 함수의 기본 값은 null이며, 데이터 송수신이 완료 되어야
data?.message값이 true가 되어 {uri: data.message} 출력
<StyledImage source={data?.message ? {uri: data.message} : null}>
</StyledImage>
{error?.message} 는 비동기 통신이 성공이든 실패든 catch를 통해 error를
받아오기 전까지는 error.message가 존재하지 않으므로 출력 안됨
<ErrorMessage>{error?.message}</ErrorMessage>
useFetch.js
import { useState, useEffect } from 'react';
//useFetch 함수 실행시 url 매개변수를 받고 => 애로우 함수 뒤에 있는 코드를 실행
export const useFetch = url => {
//데이터를 담는 통 (변수명과 setter 존재)
//data, data, inProgress 3가지 변수를 갖오 있으므로 각자 useState로 데이터 관리 객체 생성
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [inProgress, setInProgress] = useState(false);
//컴포넌트 랜더링마다 특정 작업 실행
//(비동기 실행은 한 페이지에서 주기적 실행이므로) useEffect함수를 사용하여 주기적 실행 내용 작성
useEffect( () => {
//async 비동기 처리 문법 시작
//fetchData 함수를 실행할 때 () 매개면수는 없으나,
//동기적이 아니라 fetchData함수 한 개가 비동기 처리가 진행
const fetchData = async () => {
try {
//setInProgress 변수를 통해서 비동기 실행시점과 종료시점을 찾아 관리
setInProgress(true);
//await 비동기 시 서버에서 데이터를 받아올 때까지 기다리기
const response = await fetch(url);
const result = await response.json();
//데이터를 잘 받아옴을 확인
//response 객체는 request요청에 따른 서버의 응답 데이터를 담는 문구
if(response.ok) {
setData(result);
setError(null);
}else {
throw result;
}
//request로 요청한 데이터가 정상적으로 받아오지 못할 경우 exception을 통해
//error 변수에 에러 메서지 저장
}catch (error) {
setError(error)
}finally {
setInProgress(false);
}
};
fetchData();
}, []);
return {data, error, inProgress};
}
App.js
import {View} from 'react-native';
import Counter from './components/chapter03/Counter';
import { useState } from 'react';
import { Switch } from 'react-native';
import styled, { ThemeProvider } from 'styled-components';
import {lightTheme, darkTheme} from './theme';
import Dog from './components/chapter06/Dog';
const Container = styled.View`
flex: 1;
background-color: ${props => props.theme.background}
align-items: center;
justify-content: center;
`;
const App = () => {
const [isDark, setIsDark] = useState(false);
const _toggleSwitch = () => setIsDark(!isDark);
return (
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
<Container>
<Switch value={isDark} onValueChange={_toggleSwitch} />
<Counter />
<Dog />
</Container>
</ThemeProvider>
)
}
export default App;
728x90
'STUDY > React' 카테고리의 다른 글
[React] 리액트 기초 개념 정리 (DOM, JSX, Element) (2) | 2025.01.03 |
---|---|
[React] 다크모드버튼, 카운트버튼 만들기 (0) | 2022.09.13 |
[React] 리액트 초보자 입문 강의 정리 (0) | 2022.09.06 |