본문 바로가기
React

230120 React News API 사용

NewsAPI

+)Endpoint-접속주소(?)
/도 쿼리파람이 비어 있다. 

 

 

 

App.js

import { Route, Routes } from "react-router-dom";
import NewsHome from "./component2/NewsHome";
import Header from './layout/Header';

const App = () => {

    return (
        <Routes>
            <Route element={<Header/>}>
                <Route path="/" element={<NewsHome/>}/>
                <Route path="/:category" element={<NewsHome/>}/>
            </Route>
        </Routes>
    )
}

export default App;

:category로 키 부여.

두개인 것은 홈화면과 all을 포함한 카테고리를 받았을 때를 표현하기 위한 것.

중첩라우터가 아니다! 둘 다 따로 보여주는 것.


NewsHome.js

import { Fragment } from "react";
import NewsCategory from "./NewsCategory";
import NewsList from "./NewsList";

const NewsHome = () => {
    return (
        <Fragment>
            <NewsCategory />
            <NewsList />
        </Fragment>
    )
}

export default NewsHome;

NewsCategory.js

import { NavLink } from "react-router-dom";

const NewsCategory = () => {
    /*
    business 
    entertainment 
    general 
    health 
    science 
    sports 
    technology
    1. 카테고리 맵회전
    2. 라우터설정
    3. NewsList에서는 라우터값을 처리
    */

    const category = [
        {name:"all",topic:"전체"},
        {name:"business", topic:"비지니스"},
        {name:"entertainment", topic:"연예"},
        {name:"general", topic:"일반"},
        {name:"health", topic:"건강"},
        {name:"science", topic:"과학"},
        {name:"sports", topic:"스포츠"},
        {name:"technology", topic:"기술"},
    ]

    const myStyle={color:"teal",borderBottom:"3px solid aqua"};

    return (
        <ul>
            {category.map((item,index)=><li key={index+1}>
                <NavLink to={item.name==='all'?'/':`/${item.name}`} style={({isActive})=>isActive?myStyle:undefined}>{item.topic}</NavLink></li>)}
        </ul>
    )
}

export default NewsCategory;

to에 /값. 삼항연산자 사용. 

NavLink로 활성화때 스타일부여.


NewsList.js

import axios from "axios";
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import NewsArticle from "./NewsArticle";
import styled from './NewsList.module.css'

const NewsList = () => {
    
    //1. API 가져오기
    //개인 키
    
    //5. 라우터로 들어오는 값에 처리
    const {category}=useParams();
    
    const query=(category || 'all')==='all'?'':`&category=${category}`; 
    //category가 없거나 undefined이면 all로 할당됨




    //2. useEffect에서 화면로딩시 데이터처리

    const [data, setData] = useState();


    useEffect(() => { //useEffect는 내장함수이므로 그대로 사용하고, 안에 즉시실행함수 만들어서 async await 사용
        (async () => {
            const url = `https://newsapi.org/v2/top-headlines?country=kr${query}&apiKey=개인 키`;
            let { data: { articles } } = await axios.get(url);
            setData(articles);
            setLoading(true);
        })()
    }, [query] ) //6.변화가 일어날때 마다 재실행할 변수

    //3. 데이터 로딩처리 (데이터가 오기전에 state는 undefined)
    const[loading, setLoading] = useState(false);
    if(loading===false){
        return <div>로딩중</div>
    }

    //4.li태그를 컴포넌트로 변경

    return (
        <div className={styled.news_container}>
            <h3>오늘의 헤드라인</h3>
            <ul className={styled.news_wrap}>
                {
                    /* 1.url,urlToImage,title,author,description,publishedAt */
                    data.map((item, index) =><NewsArticle key={index+1} item={item}/>)
                    /* 중간에 깨져있는 건 보낼 때 깨진 것. 복구가안됨 */
                }
            </ul>
        </div>
    )
}

export default NewsList;

-useEffect는 내장함수이므로 그대로 사용하고, 안에 즉시실행함수 만들어서 async await 사용.

 

 

JS ||연산자

 const {category}=useParams();
 const query=(category || 'all')==='all'?'':`&category=${category}`; 
    //category가 없거나 undefined이면 all로 할당됨

(a || b)면, 둘 중 하나라도 true면 true를 반환. 

둘 다 false면 마지막을 반환.

위의 경우, category와 'all'은 둘 다 false로 본다. 그래서 없거나, undefined거나, all이면 다 all로 반환하고,

삼항연상자를 통해 query는 공백이 된다. 

 

이 과정이 끝난 query를 url에 넣어주는데, category는 NewsAPI를 통해 어떤 기능을 수행한다.

즉, NewsAPI에서 category를 통해 사용할 기능을 가지고 있는 것.


NewsList.module.css

.news_container{
    padding: 50px 40px;
}

.news_wrap{
    display: flex;
    flex-direction: column;
}

.news_wrap li{
    position: relative;
    min-height: 150px;
    padding-left: 200px;
}

.news_wrap li img{
    position: absolute;
    left: 0;
    top: 0;
    width: 150px;
    height: 100px;
}

.news_wrap li a{
    color: black;
    text-decoration: none;
}

 


NewsArticle.js

const NewsArticle = ({item}) => {

    const {url,urlToImage,title,author,publishedAt,description}=item;
    let date=new Date(publishedAt);
    let year=date.getFullYear();
    let month=date.getMonth()+1;
    let day=date.getDate();

    return (
        <li>
            <a href={url}>
                <img src={urlToImage} alt={title} />
                <div>
                    <p>{author===null?"기자없음":author}</p>
                    <p>{`${year}년 ${month}월 ${day}일`}</p>
                    <p>{title}</p>
                    <p>{description}</p>
                </div>
            </a>
        </li>
    )
}


export default NewsArticle;

여기서 item은 props를 통해  NewsList에서 전달받은 것이다.

 

 

링크를 누르면 해당 카테고리에 맞는 기사가 출력된다.

 

'React' 카테고리의 다른 글

230125 React useContext()훅  (0) 2023.01.25
230125 React Context API  (0) 2023.01.25
230120 React Axios async(), await()  (0) 2023.01.20
230120 React Axios  (0) 2023.01.20
230120 React Ajax로 외부 데이터 통신하기  (0) 2023.01.20