[장고/리액트] 리액트와 장고(DRF) 연동하기- (3) CORS 해결, 리액트, 장고 연동

- 리액트 앱 만들기

간단한 앱을 만들어보자!

 

이름은 React-Practice로 했다.

yarn create react-app React-Practice

 

RestAPI.css와 RestAPI.js를 추가해주었다.

css는 앱을 보기 좋게 하기 위해 추가한 거라 필수는 아니다.

 

[App.js]

App에 RestAPI 컴포넌트를 추가해준다.

import "./App.css";
import RestAPI from "./RestAPI.js";
import React from "react";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <RestAPI />
      </header>
    </div>
  );
}

export default App;

 

[RestAPI.js]

하단에 전체 코드있습니다.

 

- 우선 HTTP request를 위해 axios를 설치한다.

yarn add axios

 

 

- 컴포넌트에서 쓰일 useState와 axios를 불러와준다!

 

 

- GET 메서드로 불러오는 객체를 담을 곳을 useState로 만들었고, 빈 배열로 초기화했다.

- POST 버튼을 클릭할 때, title과 content를 서버에 업로드한다.

 

 

- 데이터를 가져오는 GET 버튼도 만들어보자

 

 

- setText로 추가됐던 데이터들을 화면에 보여준다.

- DELETE 버튼으로 axios.delete()로 DB에 저장되어 있는 내용을 삭제하고, setText를 이용해 화면에서도 지웠다.

 

 

[전체 코드]

 

[RestAPI.js]

import React, { useState } from "react";
import axios from "axios";
import "./RestAPI.css";

function RestAPI() {
  const [text, setText] = useState([]);

  return (
    <>
      <h1>REST API 연습</h1>
      <div className="btn-primary">
        <button
          onClick={() => {
            axios
              .post("http://127.0.0.1:8000/review/", {
                title: "제목",
                content: "내용",
              })
              .then(function (response) {
                console.log(response);
              })
              .catch(function (error) {
                console.log(error);
              });
          }}
        >
          POST
        </button>
        <button
          onClick={() => {
            axios
              .get("http://127.0.0.1:8000/review/")
              .then((response) => {
                setText([...response.data]);
                console.log(response.data);
              })
              .catch(function (error) {
                console.log(error);
              });
          }}
        >
          GET
        </button>
      </div>
      {text.map((e) => (
        <div>
          {" "}
          <div className="list">
            <span>
              {e.id}번, {e.title}, {e.content}, {e.update_at}
            </span>
            <button
              className="btn-delete"
              onClick={() => {
                axios.delete(`http://127.0.0.1:8000/review/${e.id}`);
                setText(text.filter((text) => text.id !== e.id));
              }}
            >
              DELETE
            </button>{" "}
          </div>
        </div>
      ))}
    </>
  );
}

export default RestAPI;

 

 

- 장고, 리액트 서버 열기

 

[장고]

python manage.py runserver

[리액트]

yarn start

 

각 명령어로 서버를 열어준다.

localhost:8000/review/ 로 drf 창을 열고, localhost:3000/ 로 리액트를 띄운다.

 

 

리액트 앱에서 버튼을 클릭하면 다음과 같은 오류가 뜬다.

도메인 이름이 서로 다른 사이트끼리 API 요청할 때 공유를 설정하지 않았다면 CORS 오류가 발생한다!

장고는 8000이지만 리액트는 3000이기 때문에 발생!

 

- CORS 오류 해결

 

다시 장고로 돌아가자

 

- django-cors-headers를 설치한다.

pip install django-cors-headers

 

- settings.py를 수정한다.

총 다섯 가지 항목을 수정/추가한다.

ALLOWED_HOSTS = ['*']

INSTALLED_APPS = [
	...,
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...,
]

CORS_ORIGIN_WHITELIST = ('http://127.0.0.1:3000', 'http://localhost:3000')
CORS_ALLOW_CREDENTIALS = True

 

 

이제 리액트 앱으로 돌아가서 잘 동작하는지 확인해보자

POST 버튼을 세 번 누르고 GET 버튼을 누른 결과다

 

 

 

localhost:8000/review/로 이동해서 데이터가 잘 담아졌는지 확인해보자!!

얏호!

 

 

DELETE 버튼을 눌러보자

 

 

 

다시 localhost:8000/review/ 로 이동하잣

 

 

사라졌다...!! 매직...🧙

 


 

이렇게 세 개의 글에 걸친 리액트 장고 연동이 끝났다...

구글링 하며 공부하고 앱을 만들었는데, 아직 많이 부족한 거 같다

더 깔쌈하게 코드 짜고, 깔끔하게 글 작성하고 싶다,, 

320x100