News API를 이용한 웹페이지입니다.
api 사용이 localhost에서만 가능하기 때문에 배포는 진행하지 않았습니다.





function App() {
return (
<div className="flex justify-center">
<div className="flex flex-col items-center sm:w-4/5">
<Header />
<div className="flex flex-col items-center sm:items-start sm:flex-row">
<Navbar />
<Outlet />
</div>
<Footer />
</div>
</div>
);
}
Outlet을 사용하여 Header와 Navbar는 그대로 있게 하고, 내부 기사만 바꾸었습니다.
const router = createBrowserRouter([
{
path: '/',
element: <App />,
children: [
{
index: true,
element: <NewsList />,
},
{
path: ':category',
element: <NewsList />,
},
{
path: 'news/:newsId',
element: <NewsDetail />,
},
{
path: 'search/:search',
element: <NewsList />,
},
],
},
]);
NewsList와 NewsDetail이 Outlet에 들어가는 컴포넌트입니다.
const { search, category } = useParams();
useEffect(() => {
const loadData = async () => {
let response;
if (search) {
response = await searchRealData(search);
} else {
response = await defaultRealData();
}
if (category) {
response = await categoryRealData(category);
}
setData(response.data.articles);
};
loadData();
}, [search, category]);
useParams을 사용하여 파라미터를 가져오고, 이를 이용하여 해당 상황에 맞는 데이터를 받아옵니다. 데이터를 부르는 함수는 realData.js 파일에 따로 분리를 했습니다.
import axios from 'axios';
export async function defaultRealData() {
return await axios.get(`
https://newsapi.org/v2/top-headlines?country=kr&apiKey=${process.env.REACT_APP_NEWS_API}`);
}
...
defaultRealData(), searchRealData(), categoryRealData() 세 개의 함수가 있습니다. api key는 .env에 저장해뒀습니다.
return (
<div className="sticky top-0 sm:top-8 flex flex-col justify-between w-full sm:w-1/6 sm:h-80 sm:mr-8 p-2 sm:p-4 rounded-md bg-gray-100">
<p className="text-center sm:text-left mb-2 sm:mb-0 h-1/6 text-2xl text-gray-700 font-bold">
category
</p>
<div className="grid grid-cols-3 text-center sm:text-left sm:flex sm:flex-col sm:h-5/6 sm:justify-around text-sm sm:text-lg text-gray-500">
<Link
to="/business"
className="hover:text-gray-600 hover:font-semibold hover:scale-y-110"
>
business
</Link>
...
</div>
</div>
);
tailwind css는 간편했지만 반응형 웹페이지를 만들 때는 조금 불편했습니다.
화면 사이즈에 따른 className을 한 줄에 적용하다 보니 코드가 한눈에 들어오지 않았습니다.
기능 연습, 작은 프로젝트를 진행할 때는 유용하게 사용할 수 있을 것 같습니다. 😄👍