import axios from "axios";
import React, { useEffect, useState } from "react";
import styled from "styled-components";
import NewsItems from "./NewsItems";
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);
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=cecec5a2918645be8f6bddfc01c8f07d');
setArticles(res.data.articles);
} catch (e) {
console.log(e);
}
setLoading(false);
}
fetchData();
}, []);
if (loading) {
return <NewsListBlock>로딩중...</NewsListBlock>
}
if (!articles) {
return null;
}
return (
<NewsListBlock>
{articles.map(article => <NewsItems key={article.url} article={article} />)}
</NewsListBlock>
);
};
export default NewsList;
const categories = [
{
name: 'all',
text: '전체보기',
},
{
name: 'business',
text: '비즈니스',
},
{
name: 'entertainment',
text: '엔터테인먼트',
},
{
name: 'health',
text: '건강',
},
{
name: 'scinece',
text: '과학',
},
{
name: 'sports',
text: '스포츠',
},
{
name: 'technology',
text: '기술',
},
];
const Categories = () => {
return (
<CategoriesBlock>
{categories.map(c => <Category key={c.name}>{c.text}</Category>)}
</CategoriesBlock>
)
}
export default Categories;
App.js
import axios from "axios";
import React, { useCallback, useState } from "react";
import Categories from "./component/Categories";
import NewsList from "./component/NewsList";
const App = () => {
const [category, setCategory] = useState('all');
const onSelect = useCallback(category => setCategory(category), []);
return <>
<Categories category={category} onSelect={onSelect} />
<NewsList category={category} />
</>
}
export default App;
Categories.js
const Categories = ({ category, onSelect }) => {
return (
<CategoriesBlock>
{categories.map(c =>
<Category
key={c.name}
active={category === c.name}
onClick={() => onSelect(c.name)}>
{c.text}
</Category>)}
</CategoriesBlock>
)
}
import axios from "axios";
import React, { useEffect, useState } from "react";
import styled from "styled-components";
import NewsItems from "./NewsItems";
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 = ({ category }) => {
const [articles, setArticles] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const query = category === 'all' ? '' : `&category=${category}`;
const res = await axios.get(`https://newsapi.org/v2/top-headlines?country=kr${query}&apiKey=cecec5a2918645be8f6bddfc01c8f07d`);
setArticles(res.data.articles);
} catch (e) {
console.log(e);
}
setLoading(false);
}
fetchData();
}, [category]);
if (loading) {
return <NewsListBlock>로딩중...</NewsListBlock>
}
if (!articles) {
return null;
}
return (
<NewsListBlock>
{articles.map(article => <NewsItems key={article.url} article={article} />)}
</NewsListBlock>
);
};
export default NewsList;
import axios from "axios";
import React, { useCallback, useState } from "react";
import { Route } from "react-router";
import NewsPage from "./component/NewsPage";
const App = () => {
return <>
<Route path="/:category?" component={NewsPage} />
</>
}
export default App;
import React from "react";
import Categories from "./Categories";
import NewsList from "./NewsList";
const NewsPage = ({ match }) => {
const category = match.params.category || 'all';
return (
<>
<Categories />
<NewsList category={category} />
</>
)
}
export default NewsPage;
const Categories = ({ category, onSelect }) => {
return (
<CategoriesBlock>
{categories.map(c =>
<Category
key={c.name}
active={category === c.name}
exact={'all' === c.name}
to={c.name === 'all' ? '/' : `/${c.name}`}>
{c.text}
</Category>)}
</CategoriesBlock>
)