프로젝트 설명 : 대나무숲

  1. Django-backend : API 호출 ( 글 저장 / 글 가져오기 / 글 삭제)
  2. React-Frontend : 간단한 글 쓰기 및 보여주기 , 삭제
  3. Axios : http 통신 (비동기 통신)

Install 필요한 패키지 설치

1
2
pip install django-restframework
pip install django-cors-headers

Run DB 마이그래이션

1
2
3
python manage.py makemigrations
python manage.py migrate
python manage.py runserver

BACKEND API명세

URL METHOD Description Params Return
/api/posts GET 전체 글을 조회합니다. […{Post}]
/api/posts POST 새로운 글을 작성합니다. {Post}
/api/posts/[id] GET 특정 ID의 글을 조회합니다. {Post}
/api/posts/[id] DELETE 특정 ID의 글을 삭제합니다.

React app 생성

1
2
3
4
5
npx create-react-app reactfrontend
# 시작
npm start
# promise 기반의 http 통신 (비동기 통신)
npm install axios

React App에 src/api.js 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// axios 를 사용하는 js
import axios from "axios"

axios.defaults.baseURL = "http://127.0.0.1:8000/api"


export default {
// 모든 글 불러오기
getAllPosts(){
return axios.get('/posts/')
}
,
// 글 작성하기
createPost(data){
return axios.post('/posts/', data)
},
// 글 삭제하기
deletePost(id){
return axios.delete('/posts/'+String(id))
},

}

글을 써주고 삭제할수 있게 해주는 PostView.js 컴포넌트 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React, {Component} from 'react'

// const dumy_prop = {
// title: '테스트용 타이틀',
// content: '테스트용 글 입니다',
// }

export default class PostView extends Component{
render(){
const {id, title, content} = this.props
return(
<div>
{id}
<h3>{title}</h3>
<p>{content}</p>
</div>
)
}
}

app.js -> index.js main 컴포넌트인 App.js 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import React from 'react';
import './App.css';
import api from './api';
import PostView from './Components/PostView'

class App extends React.Component {
constructor(props){
super(props)
this.state = {
title: '',
content: '',
results: [],
}
}

componentDidMount(){
this.getPosts()
}

async getPosts(){
const _results = await api.getAllPosts()
//_results.data에는 아무 데이터가 없다. -> 비동기
this.setState({results: _results.data})
console.log(_results)
}

handlingChange = (event)=> {
this.setState({[event.target.name]: event.target.value})
}

handlingSubmit = async (event) => {
event.preventDefault() //event의 기능 -> 막는다
let result = await api.createPost({title: this.state.title, content: this.state.content})
console.log("완료! "+ result)
this.setState({title: '', content: ''})
this.getPosts()
}
handlingDelete = async (event) => {
await api.deletePost(event.target.value)
this.getPosts()
}


render(){
return (
<div className="App">
<div className="PostingSection">
<h2>대나무 숲 작성하기</h2>
<form onSubmit={this.handlingSubmit}>
<input
name="title"
value={this.state.title}
onChange={this.handlingChange}
/>
<textarea
name="content"
value={this.state.content}
onChange={this.handlingChange}
/>
<button type ="submit">제출하기</button>
</form>
</div>

<div className="ViewSection">
{
this.state.results.map((post) =>
<div>
<PostView key = {post.id} id = {post.id} title = {post.title} content = {post.content}/>
<button value = {post.id} onClick={this.handlingDelete}>삭제하기</button>
</div>
)
}
</div>
</div>
);
}
}

export default App;

Uncaught TypeError: Cannot read property ‘map’ of undefined

비동기이기 때문에 결과값을 가져오기전에 넘어가버린다

-> async / await 써줘야함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
getPosts(){
const _results = api.getAllPosts()
//_results.data에는 아무 데이터가 없다. -> 비동기
this.setState({results: _results.data})
console.log(_results)
}

--------------------------------------

async getPosts(){
const _results = await api.getAllPosts()
//_results.data에는 아무 데이터가 없다. -> 비동기
this.setState({results: _results.data})
console.log(_results)
}

실행결과

project

하루를 기록하다