loading

새소식

JS Library/React

[React] 리액트 실습 : 외부 API 연동 후 뉴스 앱 만들기

  • -
728x90
반응형

 

외부 서버로부터 데이터 받아오는 코드

data = axios.get(' ');

data.then(response => { })

 

1) 

  const onClick = () => {
    const data = axios.get('https://jsonplaceholder.typicode.com/todos/1/');
    data.then(response => {
      setData(response.data)
    })
  }

 

↕ 같은내용

  const onClick = async() => {
    const data = axios.get('https://jsonplaceholder.typicode.com/todos/1/');
      setData(response.data)
  }

await 코드가 사용될때에는 코드를 감싸는 함수에 async 키워드를 사용해야한다.

 

2)

    function getData1() {
      const data = fetch('http://ggoreb.com/api/lotto.jsp?drwNo=1');
      data.then((res) => res.json()).then((res) => {
        for(let key in res) {
          div.innerHTML += `<p>${res[key]}</p>`;
        }
      });
    }
    getData1();

 

    async function getData2() {
      const data = await fetch('http://ggoreb.com/api/lotto.jsp?drwNo=1');
      const res = await data.json();
      for(let key in res) {
        div.innerHTML += `<p>${res[key]}</p>`;
      }
    }
    getData2();

  </script>
</body>

 

완성코드

// NewsList.jsx //

import React from 'react';
import styled from 'styled-components';
import NewsItem from './NewsItem';
import { useState, useEffect } from 'react';
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 sampleArticle = {
    title: '제목',
    description: '내용',
    url: 'http://ggoreb.com',
    urlToImage: 'https://via.placeholder.com/160'
}
const NewsList = () => {
    const [articles, setArticles] = useState(null);
    const [loading, setLoading] = useState(false);
    useEffect(() => {
        const fetchData = async () => {
            setLoading(true);
            try {
                const response = await axios.get(
                    'https://newsapi.org/v2/top-headlines' +
                    '?country=kr&apiKey=9f5baf7d9f3f42879a20d7d19d9886e4'
                );
                setArticles(response.data.articles);
            } catch (e) {
                console.log(e);
            }
            setLoading(false);
        };
        fetchData();
    }, []);
    if (loading) {
        return <NewsListBlock>대기 중...</NewsListBlock>;
    }
    if (!articles) {
        return null;
    }
    return (
        <NewsListBlock>
            {articles.map(article => {
                return <NewsItem key={article.url} article={article} />;
            })}
        </NewsListBlock>
    );
};
export default NewsList;

// NewsItem.jsx //

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>
            <div className="thumbnail">
                <a href={url} target="_blank">
                    <img src={urlToImage} alt="thumbnail" />
                </a>
            </div>
            <div className="contents">
                <h2>
                    <a href={url} target="_blank">
                        {title}
                    </a>
                </h2>
                <p>{description}</p>
            </div>
        </NewsItemBlock>
    );
};
export default NewsItem;

// App.js //

import NewsList from "./Components/NewsList"; 
const App = () => {
  return (
    <NewsList />
  );
};
export default App;

 

728x90
반응형
Contents

📝 포스팅 주소를 복사했습니다 📝

이 글이 도움이 되었다면 공감 부탁드립니다👍