이 게시글은
Flask + React 프로젝트를 만드는 방법 | 파이썬 백엔드 + 리액트 프론트엔드
영상을 정리한 글입니다.
React와 Flask 웹 서버를 연동한 웹 애플리케이션 프로젝트를 만들어보자!
프로젝트 폴더에 flask-server
폴더를 생성한다.
이 파일에 서버와 관련된 파일들이 들어가게 될 것이다.
생성한 flask-server
폴더에 가상환경을 생성해보자
flask-server
폴더에 들어간 후 터미널에서
python3 -m venv venv
명령어를 실행하여 venv
라는 가상환경을 만든다.
터미널에서 아래의 명령어를 통해 venv
가상환경을 실행한다.
source venv/bin/activate
가상환경을 실행한 상태에서 flask를 설치한다.
pip3 install Flask
이제 python 파일 안에 flask를 import 하면 flask 사용이 가능하다!
오류
flask import를 해도 VScode에서 설치한 flask를 인식하지 못하는 오류가 발생했는데
VScode로flask-server
파일을 바로 열면 해당 문제가 발생하지 않는다.
심지어 실행에도 전혀 문제가 없어 더 자세한 이유는 찾아봐야 할 것 같다...
간단한 user 데이터를 client와 주고 받을 수 있도록 서버 파일을 생성해보자.
flask-server
폴더 안에 server.py
파일을 하나 생성하여 아래 코드를 작성한다.
from flask import Flask # Flask
app = Flask(__name__)
@app.route('/users')
def users():
# users 데이터를 Json 형식으로 반환한다
return {"members": [{ "id" : 1, "name" : "yerin" },
{ "id" : 2, "name" : "dalkong" }]}
if __name__ == "__main__":
app.run(debug = True)
python server.py
위 명령을 실행하여 서버 파일을 실행한다.
http://127.0.0.1:5000
에서 서버가 돌아가고 있음을 알 수 있다.
127.0.0.1:5000/users
를 통해 (1)에서 작성한 코드에 따라 users Json 데이터에 접근할 수 있다.
프로젝트 파일 안에서 아래의 명령어를 터미널에서 실행한다.
npx create-react-app client
client
라는 이름의 react 프로젝트가 만들어졌다.
npm start
명령어를 실행하면
localhost:3000
에서 웹이 실행되는 것을 확인할 수 있으며 해당 주소로 접속하면 아래와 같은 화면을 볼 수 있다.
React 프로젝트 파일 안에 index.css
, logo.svg
, App.test.js
같은 파일은 삭제하고 다른 파일 안에 삭제한 파일들을 import하는 코드도 삭제한다.
React에서 Flask 서버에 접근할 수 있도록 설정한다.
React 프로젝트 안에서 htttp://127.0.0.1:5000
주소에 직접 접근하려고 하면 오류가 발생한다. (CORS issues)
이를 해결하기 위해 React에 proxy를 구성해주어야 한다.
package.json 파일에 proxy를 추가해준다.
flask 서버의 주소를 값으로 넣어준다.
이제 "/users"
주소를 이용하여 "htttp://127.0.0.1:5000/users"
에 있는 데이터에 접근할 수 있다.
아래와 같이 App.js
코드를 작성하여 데이터에 잘 접근되었는지 확인한다.
useEffect
를 이용하여 웹을 처음 실행할 때만 데이터를 받아오는 작업을 실행하도록 한다.fetch
를 통해 주소에 있는 데이터를 GET 해온다.import { useEffect } from 'react';
import './App.css';
function App() {
useEffect(() => {
fetch("/users").then(
// response 객체의 json() 이용하여 json 데이터를 객체로 변화
res => res.json()
).then(
// 데이터를 콘솔에 출력
data => console.log(data)
)
},[])
return (
<div className="App">
</div>
);
}
export default App;
⚠️ 오류
잘 연결되다가 가끔 http://127.0.0.1:5000/
에 접근이 불가능하다고 뜨는 오류가 발생했다.
출처 에서 확인한 결과
맥북의 AirPlay 기능 때문에 발생한 오류여서 AirPlay 설정에 들어가 기능을 꺼주었다.
React 앱을 실행하여 콘솔을 확인해보면
해당 주소의 데이터를 잘 받아온 것을 확인할 수 있다.
받은 데이터를 화면에 간단하게 출력해보자
useState
이용하여 data를 저장할 state 변수 data
와 state 변경 함수 setData
를 만든다.setData
함수를 통해 data
state를 변경해준다. -> 화면이 re-rendering 될 것이다.import React from 'react';
import { useState, useEffect } from 'react';
function App() {
// state
const [data, setData] = useState([{}])
useEffect(() =>
{
fetch("/users").then(
response => response.json()
).then(
data => {
// 받아온 데이터를 data 변수에
setData(data);
}
).catch(
(err) => console.log(err)
)
}, [])
return (
<div className='App'>
<h1>test 하는 중...</h1>
<div>
{data.users.map((u) => <p key={u.id}>{u.name}</p>)}
</div>
</div>
)
}
export default App;
⚠️ 위의 처럼만 작성하면 화면에 아무것도 뜨지 않는다.
콘솔을 살펴보면
undefined
의 map
를 적용할 수 없다는 오류가 뜬다.
data를 잘 받아왔는데 왜 data.users
가 undefined
라는 걸까?
fetch
는 비동기적으로 작동하기 때문에 실행이 완료되지 않아도 렌더링하는 코드가 먼저 실행될 수 있다.fetch
가 완료되어 데이터를 다 받아오기 전까지 data.users
는 undefined
일 것이다.import React from 'react';
import { useState, useEffect } from 'react';
function App() {
// state
const [data, setData] = useState([{}])
useEffect(() =>
{
fetch("/users").then(
response => response.json()
).then(
data => {
// 받아온 데이터를 data 변수에 update
setData(data);
}
).catch(
(err) => console.log(err)
)
}, [])
return (
<div className='App'>
<h1>test 하는 중...</h1>
<div>
{/* 삼항연산자 */}
{ (typeof data.users === 'undefined') ? (
// fetch가 완료되지 않았을 경우에 대한 처리
<p>loding...</p>
) : (
data.users.map((u) => <p>{u.name}</p>)
)}
</div>
</div>
)
}
export default App;
다시 React를 실행하면 결과가 잘 나오는 것을 확인할 수 있다.
좋은 정보 감사합니다