도리쓰에러쓰

[React] React에서의 Ajax 요청 방법 / axios 설치 본문

코딩애플 (React)/기초수업 (코딩애플) - 2

[React] React에서의 Ajax 요청 방법 / axios 설치

강도리 2022. 1. 19. 00:37

저번 게시물에 이어서 작성하겠습니다. (코드 참고)

 

[React] Lifecycle Hook(예전 문법) vs useEffect(요즘 문법)

저번 게시물에 이어서 작성하겠습니다. (코드 참고) [React] SASS 개념, 설치 및 기본 문법 저번 게시물에 이어서 작성하겠습니다. (코드 참고) [React] styled-components를 이용한 class없는 CSS 스타일링 저

dori-coding.tistory.com


1. Ajax란?

서버에 새로고침 없이 요청을 할 수 있게 도와줍니다.

 

서버는 누군가 요청을 하면 데이터를 가져다주는 프로그램입니다.

 

요청은 서버에 요청하는 방법을 뜻하는데, 크게 사용하는 요청 방법은 2가지입니다.

- GET : 데이터, 웹페이지 같은 것을 읽고 싶을 때 서버에 보내는 요청입니다. (데이터 조회)

- POST : 데이터를 서버로 보내고 싶을 때 서버에 보내는 요청입니다. (데이터 생성하여 전달)

 

Ajax에 대해서 더 알고 싶다면 아래 게시물을 참고해주세요!

 

[Ajax] Ajax 시작하기

1. Ajax(Asynchronous Javascript And XML)란? 서버와 클라이언트 간에 정보를 비동기적으로 전달하기 위해 JavaScript에서 사용하는 하나의 라이브러리 웹은 클라이언트와 서버로 나뉘어져 서로 통신을 통해

dori-coding.tistory.com


2. Ajax를 사용하는 방법

1) jQuery 설치하여 $.ajax() 사용

2) axios 설치하여 axios.get() 사용

3) 순수 자바스크립트 문법 fetch() 사용

 

저는 이 중에 axios를 설치하여 사용할 겁니다.

React나 Vue에서 호환성이 좋아 자주 사용하는 라이브러리이기도 합니다.


3. axios 라이브러리 설치

1) 터미널에 npm install add axios 혹은

  yarn이 설치되어 있으신 분들은 yarn add axios를 입력하여 axios 라이브러리를 설치합니다.

 

2) axios import 하기

import axios from 'axios';

4. axios 이용하여 서버에서 데이터 가져오기

저는 서버에 ajax 요청을 해서 상품 데이터 3개를 더 가져올 겁니다.

 

상품 데이터 3개 정보 (data.js)

export default [
    {
        id : 0,
        title : "Black Jacket",
        content : "Born in Paris",
        price : 6000000
    },

    {
        id : 1,
        title : "White Bag",
        content : "Born in Paris",
        price : 5000000
    },

    {
        id : 2,
        title : "Black Bag",
        content : "Born in Paris",
        price : 4000000
    },
]

1) App.js 에 '더보기' 버튼을 만듭니다.

<button className='btn btn-primary'>더보기</button>

 

2) onClick()을 이용해 버튼을 클릭하면 함수를 실행하고, ajax를 통해 데이터를 가져옵니다.

- axios.get(데이터 요청할 URL)

  * 저는 서버가 없기 때문에 코딩애플님이 만들어주신 서버 URL를 이용하였습니다.

<button className='btn btn-primary' onClick={()=>{
  axios.get('https://codingapple1.github.io/shop/data2.json');
}}>더보기</button>

 

📌 데이터 요청 성공하면?

- axios.get(데이터 요청할 URL).then()

  * then() 안에 있는 코드가 실행됩니다.

 

📌 데이터 요청 실패하면?

- axios.get(데이터 요청할 URL).catch()

  * catch() 안에 있는 코드가 실행됩니다.

<button className='btn btn-primary' onClick={()=>{
  axios.get('https://codingapple1.github.io/shop/data2.json')
  .then(()=>{
    console.log('success');
  })
  .catch(()=>{
    console.log('fail');
  })
}}>더보기</button>

 

3) Ajax로 가져온 데이터를 출력합니다.

- 자료 출력하는 방법 : .then((가져온자료)=>{})

  * 저는 변수명을 result로 하여 콘솔창에 출력하게 하였습니다.

<button className='btn btn-primary' onClick={()=>{
  axios.get('https://codingapple1.github.io/shop/data2.json')
  .then((result)=>{
    console.log(result);
  })
  .catch(()=>{
    console.log('fail');
  })
}}>더보기</button>

 

- '더보기' 버튼을 클릭하였더니 콘솔창에 자료 출력이 되었고 이 중 실제 데이터가 들어있는건 data입니다.

 

- 그래서 result.data로 출력하면 실제 데이터만 출력이 됩니다.

console.log(result.data);

* axios를 사용하면 JSON을 Object로 알아서 바꿔줍니다. (만약 순수 자바스크립트 문법 fetch()를 사용한다면 JSON으로 출력)


5. '더보기' 버튼을 누르면 상품 데이터 3개 가져온 후 메인페이지 하단에 상품 레이아웃 3개 추가하기

- 아래의 코드처럼 setProducts()로 데이터를 3개 추가하면 됩니다.

- [...배열]은 값의 주소가 아닌 내용을 copy합니다.

<button className='btn btn-primary' onClick={()=>{
  axios.get('https://codingapple1.github.io/shop/data2.json')
  .then((result)=>{ setProducts([...products, ...result.data]) })
  .catch(()=>{
    console.log('fail');
  })
}}>더보기</button>

 

- 아래 사진과 같이 [더보기] 버튼을 클릭하면 데이터가 3개에서 6개로 변경된 것을 확인할 수 있습니다.


6. 전체 코드

App.js

/* eslint-disable */
import React, { useState } from 'react'
import { Navbar, Container, Nav, NavDropdown, Button } from 'react-bootstrap';
import './App.css';
import data from './data.js';
import Detail from './Detail.js';
import axios from 'axios';

import { Link, Route, Switch } from 'react-router-dom';

function App() {

  let [products, setProducts] = useState(data);

  return (
    <div className="App">
      <Navbar bg="light" expand="lg">
        <Container>
          <Navbar.Brand href="#home">Saint Laurent</Navbar.Brand>
          <Navbar.Toggle aria-controls="basic-navbar-nav" />
          <Navbar.Collapse id="basic-navbar-nav">
            <Nav className="me-auto">
              <Nav.Link as={Link} to="/">Home</Nav.Link>
              <Nav.Link as={Link} to="/detail">Detail</Nav.Link>
              <NavDropdown title="Dropdown" id="basic-nav-dropdown">
                <NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
                <NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
                <NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
                <NavDropdown.Divider />
                <NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
              </NavDropdown>
            </Nav>
          </Navbar.Collapse>
        </Container>
      </Navbar>

      <Switch>
        <Route exact path="/">
          <div className='Jumbotron'>
            <h1>20% Season Off</h1>
            <p>
              This is a simple hero unit, a simple jumbotron-style component for calling
              extra attention to featured content or information.
            </p>
            <p>
              <Button variant="primary">Learn more</Button>
            </p>
          </div>

          <div className='container'>
            <div className='row'>
              {
                products.map((a, i) => {
                  return <Card products={a} num={i} key={i}/>
                })
              }
            </div>
            <button className='btn btn-primary' onClick={()=>{
              axios.get('https://codingapple1.github.io/shop/data2.json')
              .then((result)=>{ setProducts([...products, ...result.data]) })
              .catch(()=>{
                console.log('fail');
              })
            }}>더보기</button>
          </div>
        </Route>
        
        <Route path="/detail/:id">
          <Detail products={ products }/>
        </Route>
        
        <Route path="/:id">
            <div>아무말</div>
        </Route>
      </Switch>
    </div>
  );
}

function Card(props) {
  return(
    <div className='col-md-4'>
      <img className="img" src={ 'images/img'+ (props.num + 1) +'.jpg' } />
      <h4>{ props.products.title }</h4>
      <p>{ props.products.content }</p>
      <p>{ props.products.price }</p>
    </div>
  )
}

export default App;

 

public/images 안에 이미지 파일 3개를 추가하였습니다.

 

* 이외의 코드는 이전 게시물에 작성된 코드와 일치합니다.

Comments