axios를 설치하고 다음과 같은 코드를 작성하자.
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
|
import logo from './logo.svg';
import './App.css';
import React, {useState} from 'react';
import axios from 'axios';
function App() {
const [data, setDate] = useState(null);
const onClick = async () => {
try{
// 가짜 API를 호출할 수 있는 사이트
const response = axios.get('https://jsonplaceholder.typicode.com/todos/1');
setDate(response.data);
}
catch(err) {
console.error(err);
}
}
return (
<div>
<div>
<button onClick={onClick}>call</button>
{data && <textarea rows={7} value={JSON.stringify(data, null, 2)} readOnly={true} />}
</div>
</div>
);
}
export default App;
|
cs |
에 들어가서 회원가입을 하면 API키를 발급받을 수 있다.
그 후 https://newsapi.org/s/south-korea-news-api
에 들어가 url을 복사하고 위 코드의 axios부분에 이 url을 넣어 준다. 그 후 src/Components에 NewsItem.js를 만든다
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
//NewsItem.js
import React from 'react'; import styled from 'styled-components';
const NewsItemBlock = styled.div`
display: flex;
.thumbnail {
margin-right: 1rem;
img {
display: block;
width: 160px;
height: 100px;
object-fit: cover;
}
}
.contents {
h2 {
margin: 0;
a {
color: black;
}
}
p {
margin: 0;
line-height: 1.5;
margin-top: 0.5rem;
white-space: normal;
}
}
& + & {
margin-top: 3rem;
}
`;
const NewsItem = ({article}) => {
const {title, description, url, urlToImage} = article;
return (
<NewsItemBlock>
{urlToImage && (
<div className="thumbnail">
<a href={url} target={"_blank"} rel={"noopener noreferrer"}>
<img src={urlToImage} alt="thumbnail"/>
</a>
</div>
)}
<div className="contents">
<h2>
<a href={url} target={"_blank"} rel={"noopener noreferrer"}>
{title}
</a>
</h2>
<p>{description}</p>
</div>
</NewsItemBlock>
);
}
export default NewsItem;
|
cs |
이제 NewsList.js를 만들고 내부에서 API연동을 진행한다. 이때 axios를 그냥 async를 이용하면 안된다. useEffect는 clean-up함수를 반환하고 있기 때문이다. 따라서 useEffect 내부에서 async/await를 사용하고 싶다면 함수 내부엣 async가 붙은 또 다른 함수를 만들어서 사용해야 한다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
//NewsList.js
import React, {useState, useEffect} from 'react';
import styled from 'styled-components';
import NewsItem from './NewsItem';
import axios from 'axios';
const NewsListBlock = styled.div`
box-sizing: border-box;
padding-bottom: 3rem;
width: 768px;
margin: 0 auto;
margin-top: 2rem;
@media screen and (max-width: 768px) {
width: 100%;
padding-left: 1rem;
padding-right: 1rem;
}
`;
const NewsList = () => {
const [articles, setArticles] = useState(null);
//API요청이 대기 중인지 판별
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async() => {
setLoading(true);
try{
const res = await axios.get(
'https://newsapi.org/v2/top-headlines?country=kr&apiKey=2c88868b5a4e44dcaa072c55dac0b307'
);
setArticles(res.data.articles);
}
catch(err) {
console.error(err);
}
setLoading(false);
};
fetchData();
}, []);
if(loading) {
return <NewsList>Loading...</NewsList>
}
if(!articles){
return null;
}
return (
<NewsListBlock>
{articles.map((article) => (
<NewsItem key={article.url} article={article}/>
))}
</NewsListBlock>
);
};
export default NewsList;
|
cs |