Jieunny의 블로그
[TS] 날씨 검색 서비스 구현하기 본문
📣 OpenWeather API를 이용해서 날씨 검색 서비스 구현하기
스터디에서 각자 타입스크립트를 이용한 미니 프로젝트를 해오기로 했는데, 나는 날씨 검색 서비스를 만들기로 했다.
🚨css 랑 기능 추가하면서 밑에 적은 코드랑 조금 달라졌다
🔗 파일 구조
src
ㄴ components
ㄴ PrintWeather.tsx : 날씨가 어떤지를 출력하는 컴포넌트
ㄴ InsertCityName.tsx : 도시를 입력할 input, 검색버튼을 출력하는 컴포넌트
ㄴ img : 배경화면이 될 날씨 이미지를 가지고 있는 폴더
ㄴ type : openWeather에서 제공해주는 데이터 타입을 담고있는 폴더
ㄴ types.ts
ㄴ App.tsx : api로 데이터를 받아오고, 그에 맞는 배경화면과 다른 컴포넌트들을 모두 출력하는 컴포넌트
.env : 환경 변수를 담고 있는 파일
𝟭. OpenWeather API 이용하기
// .env
REACT_APP_API_URL = https://api.openweathermap.org/data/2.5/weather
REACT_APP_WEATHER_API_KEY = '내 API KEY'
➰ .env 파일을 생성해서 사용할 API 주소와 내 API KEY를 환경 변수로 저장한다.
// App.tsx
const api = {
//.env 파일의 환경 변수 사용
url: process.env.REACT_APP_API_URL,
api_key: process.env.REACT_APP_WEATHER_API_KEY
}
const App = () => {
const [cityName, setCityName] = useState('seoul');
// InsertCityName 컴포넌트에 props로 전달할 변수
const [weather, setWeather] = useState<WeatherData>();
// PrintWeather 컴포넌트에 props로 전달할 변수
const [weatherName, setWeatherName] = useState("");
const getWeather = async() => {
// 오픈 API에서 특정 도시 날씨 받아오기
const response = await axios.get(`${api.url}?q=${cityName}&appid=${api.api_key}`);
// cityName에 들어있는 도시의 날씨를 받아온다.
setWeather(response.data);
setWeatherName(response.data.weather[0].main);
// console.log(response.data);
}
useEffect(() => {
getWeather();
}, [cityName])
// cityName 변할 때마다 데이터 불러오기
➰ 새 변수를 선언해서, 환경 변수들을 불러와준다.
➰ axios를 사용해서 open api의 데이터를 불러와주는데, 이때 특정 도시의 날씨를 불러와야하므로 query를 이용한다.
➰ query로 전달할 도시 이름은 state로 선언해주고, 이 도시 이름은 내가 입력할 때마다 바뀌어야 하므로 InsertCityName 컴포넌트로 전달해준다.
𝟮. 불러온 데이터를 각 컴포넌트에 전달, 받아오기
➰ TS에서 props를 받아올 때는 타입까지 함께 적어주어야 한다.
// App.tsx
const weatherImg:{[key: string]: string} = {
Clear: Clear,
Clouds: Clouds,
Drizzle: Drizzle,
Rain: Rain,
Snow: Snow,
Thunderstorm: Thunderstorm,
// 각각은 이미지를 컴포넌트로 불러온 것
}
// App.tsx의 Container 컴포넌트에 배경화면으로 전달할 props
interface ContainerProps {
// Container의 props 타입 지정
img: string | undefined;
}
// interface로 props의 타입을 지정해주고
const Container = styled.div<ContainerProps>`
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-image: url(${(props) => props.img});
// 받아온 img props를 배경사진으로 설정해준다.
// 위에 <ContainerProps>로 타입 지정을 해줘야 props로 받아올 수 있다. 안받아오면 에러뜸.
transition: all 0.5s ease-in;
background-size: cover;
background-repeat: 100% 100%;
background-position: center;
`
// 사용할 컴포넌트에서 타입까지 받아준다.
return (
<Container img={weatherImg[weatherName]}>
{/* weatherName에 해당하는 이름을 img에서 찾아서 img props로 전달 */}
<Box>
<ProjectTitle>{`오늘 '${weather?.name}'의 날씨는?`}</ProjectTitle>
<PrintWeather weather={weather}/>
<InsertCityName setCityName={setCityName}/>
</Box>
</Container>
);
➰ 각 컴포넌트에 필요한 state를 props이름={props값} 으로 전달해준다.
// PrintWeather.tsx
interface Props {
// props 타입 지정해주기
weather: WeatherData | undefined;
}
const PrintWeather = ({weather} : Props) => {
return(
<Container>
<WeatherInfo>{`${weather?.weather[0].description}`}</WeatherInfo>
</Container>
)
}
➰ 받아온 props의 타입을 지정해주고, 받아올 때 타입도 표기해준다.
// InsertCityName.tsx
interface Props {
setCityName: React.Dispatch<React.SetStateAction<string>>;
//useState 의 set 함수는 TS에서의 타입이 Dispatch<React.SetStateAction<string>> 이다.
}
const InsertCityName = ({setCityName} :Props) => {
const [city, setCity] = useState('seoul');
// input칸에 입력한 city이름 담을 변수
const changeCityName = (e: React.ChangeEvent<HTMLInputElement>) => {
setCity(e.target.value);
}
➰ 받아온 props의 타입을 지정해주고, 받아올 때 타입도 표기해준다.
📣 실행 화면
'CodeStates > TS 스터디' 카테고리의 다른 글
Section14. React.js 및 TypeScript (0) | 2023.03.27 |
---|---|
Section11. TS와 함께 Webpack 사용하기 (0) | 2023.03.24 |
Section10. 모듈 및 네임스페이스 (0) | 2023.03.23 |
Section9. Drag & Drop 프로젝트 만들기 (2) | 2023.03.20 |
Section8. 데코레이터 (0) | 2023.03.03 |