[React] fetch() / 서버에 데이터 요청하기 (GET, POST)

Hyunsu Hera Choi·2022년 8월 9일
0

fetch

JS 비동기 함수.

fetch함수는 데이터를 요청(IO)하는 함수로 IO통신이 일어난다.

fetch().then().then()

IO통신은 데이터를 요청해서 결과값까지 받아야 하므로 단순히 화면을 그리는 랜더링과 속도가 맞지 않음.

  • fetch() : 요청지 주소, method headers 등 요청정보, 데이터 정보(body)

  • then() : 첫번째 then. 받을 데이터 형태의 빈깡통으로 세팅. ---> 나머지 랜더링을 계속 진행

  • then() : 두번째 then. 실제 데이터가 담기는 곳. ---> 랜더링 완료 후 두번째 then에 데이터가 있으면 다시 랜더링이 일어남.

GET 방식으로 서버에 데이터 요청

fetch('http://localhost:8080/요청지', { method : "GET" })      //메소드 방식 지정
        .then(res => res.json())              //json으로 받을 것을 명시
        .then(res => {                        //실제 데이터를 상태변수에 업데이트
            console.log(1, res);
            setValue(res);
        }); 

예)

import React, { useEffect, useState } from 'react';
import MovieItem from '../../components/MovieItem';

const Home = () => {

    const [moives, setMovies] = useState([])

    useEffect(()=> {
        fetch('http://localhost:8080/movie', {
            method : "GET"   
        }).then(res=>res.json()).then(res=>{
            console.log(1, res);
            setMovies(res);
        });              
    }, []);

    return (
        <div>
            {moives.map((movie)=>(
                <MovieItem key={movie.id} movie={movie}/>
            ))}
        </div>
    );
};

export default Home;

POST 방식으로 서버에 데이터 요청

fetch("http://localhost:8080/요청지", {
            method : "POST",          //메소드 지정
            headers : {               //데이터 타입 지정
                "Content-Type":"application/json; charset=utf-8"
            },
            body: JSON.stringify(data)   //실제 데이터 파싱하여 body에 저장
        }).then(res=>res.json())        // 리턴값이 있으면 리턴값에 맞는 req 지정
          .then(res=> {
            console.log(res);          // 리턴값에 대한 처리
          });

예)

import React, { useState } from 'react';
import { Button, Form } from 'react-bootstrap';

const AddForm = () => {

    const [movie, setMovie] = useState({
        title : '',
        director : '',
        genre : '',
        grade : 0,
        photo : ''
    });

    const handleValueChange = (e) => {
        setMovie({
            ...movie,
            [e.target.name]:e.target.value
        });
    }   

    const handleSubmit = (e) => {
        e.preventDefault(); // submit action을 안타도록 설정
        fetch("http://localhost:8080/movie", {
            method : "POST",
            headers : {
                "Content-Type":"application/json; charset=utf-8"
            },
            body: JSON.stringify(movie)
        })
        .then(res=>{
            console.log(res)
            return res.json();
        })
        .then(res=> {
            console.log(res);
        });
    }

    return (
        <Form onSubmit={(e) => handleSubmit(e)}>
            <Form.Group className="mb-3" controlId="formGridTitle">
                <Form.Label>TITLE</Form.Label>
                <Form.Control type="text" placeholder="Movie title" name="title" onChange={(e) => handleValueChange(e)}/>
            </Form.Group>

            <Form.Group className="mb-3" controlId="formGridDirector">
                <Form.Label>DIRECTOR</Form.Label>
                <Form.Control type="text" placeholder="Movie director" name="director" onChange={(e) => handleValueChange(e)}/>
            </Form.Group>

            <Form.Group className="mb-3" controlId="formGridGenre">
                <Form.Label>GENRE</Form.Label>
                <Form.Select type="checkbox" placeholder="Choose..." name="genre" onChange={(e) => handleValueChange(e)}>
                    <option>Choose...</option>
                    <option>드라마</option>
                    <option>멜로/로맨스</option>
                    <option>공포</option>
                    <option>스릴러</option>
                    <option>코미디</option>
                    <option>액션</option>
                    <option>SF</option>
                    <option>판타지</option>
                    <option>가족</option>
                    <option>다큐멘터리</option>
                    <option>전쟁</option>
                    <option>미스터리</option>
                    <option>사극</option>
                    <option>애니메이션</option>
                </Form.Select>
            </Form.Group>

            <Form.Group className="mb-3" controlId="formGridGrade">
                <Form.Label>GRADE</Form.Label>
                <Form.Control type="text" placeholder="1 ~ 10" name="grade" onChange={(e) => handleValueChange(e)}/>
            </Form.Group>

            <Form.Group className="mb-3" controlId="formGridPhoto">
                <Form.Label>PHOTO</Form.Label>
                <Form.Control type="file" name="photo" onChange={(e) => handleValueChange(e)}/>
            </Form.Group>

{/*             <Form.Group className="mb-3" id="formGridCheckbox">
                <Form.Check type="checkbox" label="Check me out" />
            </Form.Group> */}
            <Button variant="primary" type="submit">
                Submit
            </Button>
        </Form>
    );
};

export default AddForm;

then() 에서 요청결과 받아 성공/실패 처리하기

첫번째 then() 에서 상태코드로 성공했는지 실패했는지 확인 후,

두번쨰 then() 에서 성공/실패에 대한 결과 처리 해주기.

    const handleSubmit = (e) => {
        e.preventDefault(); // submit action을 안타도록 설정
        fetch("http://localhost:8080/movie", {
            method : "POST",
            headers : {
                "Content-Type":"application/json; charset=utf-8"
            },
            body: JSON.stringify(movie)
        })
        .then(res=>{
            console.log(res);
            // json 파싱 전, 상태코드 확인하여 res값 초기화
            if(res.status === 201){
                return res.json();
            }else{
                return null;
            }
        })
        .then(res=> {
            console.log(res);
            // res 값에 따른 결과 처리
            if(res !== null){
                props.history.push('/');      // 정상일 때만 HOME으로 이동
            }else{
                alert('등록을 실패하였습니다.');
            }
        });
    }

0개의 댓글