일안하고블로그

[ React ] fetch -REST API / JSONPlaceholder 본문

React/Api Client

[ React ] fetch -REST API / JSONPlaceholder

대한93 2018. 7. 20. 16:15



React fetch


작업파일은 여기를 클릭해주세요.

리액트에서 데이터를 받아올때는 어떻게 받을까? 라는 생각을 해본 적이 있을거에요.

그냥 단순히 Jquery 라이브러리를 불러서 사용을 해야하는 것인지 아니면, 다른방법이 있는지 고민을 하다가 처음 알게된 라이브러리는 fetch 입니다. 하지만 이것도 쉽지 않았습니다. 왜냐면 여러개를 테스트 해보고 싶은데 마땅히 테스트 해볼것도없고..

유튜브를 보면서 정리를 해보았습니다. 


리액트에서 쓰는 API Citent REST API는 fetch / SuperAgent / axios 가 있습니다.(다른 방법도 더찾아보면 있을거에요) 여기서 제가 선택해서 사용 할 것은 fetch(native) axios입니다. 


fetch는 ajax역할만 하는 라이브러리인데, 사용법은 생각보다 쉽습니다. 키워드는 두개에요. 

React fetch

JSONPlaceholder

우선 ,테스트 할 사이트를 둘러 보겠습니다. 사이트는 여기를 클릭해주세요.



이렇게 사이트가 영어로 나와서 구글 번역을 돌렸습니다. 




번역으로 돌려보니까 테스트용도로 지원하는 가짜 REST API라는 것을 알 수 있습니다. 

아래 보면 예시와 리소스들 그리고 경로들도 나옵니다. 

여기서, 처음 테스트를 해볼건데요, 하단에 보시면 Routes 부분에 몇가지 테이블 형식으로 구성된 도표가 보입니다. 


여기에서 첫번째로 , GET /posts가 어떻게 구성되어 있는지 보겠습니다.


https://jsonplaceholder.typicode.com/posts


저기에 있는 Data를 받아서 활용 할 것입니다. 

간단하게 살펴 보았으니, React 프로젝트를 만들어 보겠습니다. 


우선, create-react-app으로 프로젝트를 만듭니다.

$ create-react-app react-fetch

설치가 완료 되었으면, 프로젝트 폴더 이동

$ cd react-fetch

프로젝트 이동후, 실행.

$ yarn start

화면이 나오면 성공입니다.

작업을 하기위해 2개의 컴포넌트 파일을 만들겠습니다. 

만들파일은 Posts.js PostForm.js 입니다. 



이렇게 되었다면,  Posts.js를 만들어서 작업을 하겠습니다. Posts.js는 class형 컴포넌트로 만들어줍니다. 

src/components/Posts.js

import React, { Component } from 'react';

class Posts extends Component {
render() {
return (
<div>
Posts.js를 App.js에 보이도록 이동
</div>
);
}
}

export default Posts;

다음으로 App.js에 작업했던  Posts.js를 추가해줍니다. 

/src/App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Posts from './components/Posts';

class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<Posts />
</div>
);
}
}

export default App;

Posts.js에 JSONPlaceholder사이트에서 받아온 리스트를 뿌려 줄 것입니다. 

우선, 리스트를 뿌려주기 전에 간단한 리액트  LifeCycle에 대해서 알아야합니다. 

리액트개발을 할때 생명주기를 알아야 합니다. 

그것은 나중에 따로 공부를 해보겠습니다. 

저희가 알아 두어야 하는것은 컴포넌트 생성시 생명주기입니다. 

constructor  -> componentWillMount ->render 

로직 상으로 Posts.js가 실행되면 다음과같은 순서로 실행됩니다. 

/src/components/Posts.js

import React, { Component } from 'react';

class Posts extends Component {
/* 컴포넌트 생성시 */
/* 생명주기순서 : constructor(생성자) -> componentWillMount -> render */
constructor(props) {
super(props);
console.log('constructor !!');
}
componentWillMount() {
console.log('componentWillMount !!');
}
render() {
console.log('render !!');
return (
<div>
Posts.js를 App.js에 보이도록 이동
</div>
);
}
}
export default Posts;

이해를 돕기 위해서 이렇게 각각의 위치에 로그를 추가해 보았습니다.

테스트를 한번 해볼까요. 

이제 fetch 를 사용해보겠습니다. JSONPlaceholder 사이트에 있는 example 처럼 만들어 보겠습니다. 

https://jsonplaceholder.typicode.com/posts

import React, { Component } from 'react';

class Posts extends Component {
/* 컴포넌트 생성시 */
/* 생명주기순서 : constructor(생성자) -> componentWillMount -> render */
constructor(props) {
super(props);
}
componentWillMount() {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(data => console.log(data));
}
render() {
return (
<div>
Posts.js를 App.js에 보이도록 이동
</div>
);
}
}
export default Posts;

가장먼저 componentWillMount에 fetch를 합니다. 받은 데이터가 잘나오는지 확인 해보겠습니다.

데이터가 잘들어옵니다. 다음으로는 , 이제 state에 데이터를 담아  화면에 뿌려보겠습니다.

import React, { Component } from 'react';

class Posts extends Component {
/* 컴포넌트 생성시 */
/* 생명주기순서 : constructor(생성자) -> componentWillMount -> render */
constructor(props) {
super(props);
this.state = {
posts: []
}
}
componentWillMount() {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(data => this.setState({
posts: data
}));
}
render() {
const { posts } = this.state;
const postsList = posts.map((post) => (
<div key={post.id} id={post.id}>
<h4>{post.title}</h4>
<h4>{post.body}</h4>
</div>
));
return (
<div>
{postsList}
</div>
);
}
}
export default Posts;

이렇게 변경후 , 브라우저를 열어보시면

위에 이미지와 같이 리스트가 뿌려진다면, 성공입니다. 

마지막으로, 100개의 리스트에서 제가 입력한 값을 넣어서 101개의 데이터로 만들어 보겠습니다. 만들기 위해서 아까 추가했던 PostsForm.js를 추가하고 추가한 PostsForm에 간단한 폼을 만들어 줍니다. 

/src/components/PostsForm

import React, { Component } from 'react';

class PostsForm extends Component {
constructor(props){
super(props);
this.state={
title:'',
body:''
};
this.onChange =this.onChange.bind(this);
}
onChange(e){
this.setState({
[e.target.name]:e.target.value
});
}
render() {
const {title,body} = this.state;
const {onChange} = this;
return (
<div>
<h4>new Post</h4>
<form action="">
<div>
<label>title:</label>
<input type="text" name="title" value={title} onChange={onChange}/>
</div>
<div>
<label>body:</label>
<input type="text" name="body" value={body} onChange={onChange}/>
</div>
<div><button type="submit">전송</button></div>
</form>
</div>
);
}
}

export default PostsForm;

그다음 App.js를 수정합니다.

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Posts from './components/Posts';
import PostsForm from './components/PostsForm';

class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<PostsForm />
<Posts />
</div>
);
}
}
export default App;

이렇게 수정이 화면이 보이신다면, 완료 된 것입니다. 

크롬에서 저는 리액트 테스트를 할때 React Developer Tools를 사용합니다.

마지막으로 데이터를 추가해보겠습니다.

import React, { Component } from 'react';

class PostsForm extends Component {
constructor(props){
super(props);
this.state={
title:'',
body:''
};
this.onChange =this.onChange.bind(this);
this.onSubmit =this.onSubmit.bind(this);
}
onChange(e){
this.setState({
[e.target.name]:e.target.value
});
}
onSubmit(e){
e.preventDefault();
const post ={
title:this.state.title,
body:this.state.body
}
/* 전송방식은 post */
fetch('https://jsonplaceholder.typicode.com/posts',{
method :"POST",
headers:{
'content-type':'application/json'
},
body:JSON.stringify(post)
})
.then(res=>res.json())
.then(data=>console.log(data));
}
render() {
const {title,body} = this.state;
const {onChange,onSubmit} = this;
return (
<div>
<h4>new Post</h4>
<form onSubmit={onSubmit}>
<div>
<label>title:</label>
<input type="text" name="title" value={title} onChange={onChange}/>
</div>
<div>
<label>body:</label>
<input type="text" name="body" value={body} onChange={onChange}/>
</div>
<div><button type="submit">전송</button></div>
</form>
</div>
);
}
}

export default PostsForm;

기존url 과 같은 url을 사용했는데 이번 method는 POST입니다. 입력한 state정보를 가지고 

body:JSON.stringify(post)

다음과 같이 데이터를 전송해줍니다. 

return data가 저와 같이 나오시면 POST 도 성공하셨습니다.



수고하셨습니다.




Comments