( 노드 서버를 사용하고 있다면 아래 코드를 그대로 따라 입력하고 다른 서버를 사용하고 있다면 해당 서버의 언어에 맞게 바꿔 입력하기 )
const express = require('express');
const cors = require('cors');
const app = express();
const port = 3001;
app.use(cors());
app.get('/get/simple/200', (req, res) => {
console.log("클라이언트의 요청을 받았습니다.");
console.log("상태 코드 200 으로 응답합니다.");
res.status(200).send();
});
app.get('/get/simple/300', (req, res) => {
console.log("클라이언트의 요청을 받았습니다.");
console.log("상태 코드 300 으로 응답합니다.");
res.status(300).send();
});
app.get('/get/simple/400', (req, res) => {
console.log("클라이언트의 요청을 받았습니다.");
console.log("상태 코드 400 으로 응답합니다.");
res.status(400).send();
});
app.get('/get/simple/500', (req, res) => {
console.log("클라이언트의 요청을 받았습니다.");
console.log("상태 코드 500 으로 응답합니다.");
res.status(500).send();
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
<< 코드 설명 >>
(1). 클라이언트가 GET 방식으로
(2). http://localhost/get/simple/200 경로로 요청을 보낸다면
(3). 상태 코드 200으로 응답하겠다.
이제 노드 서버를 실행시키자
노드 서버를 실행시키는 명령 : node (컨트롤러 파일명)
먼저 가장 간단한 형태인 데이터 없이 GET 방식으로 서버에 요청을 보내보자
요청 경로에 따라서 서버는 200, 300, 400, 500 상태 코드로 응답함
프로젝트 -> src -> chapter04 -> Component01.jsx 파일을 추가하고 아래 코드를 추가하자
import React from 'react';
import axios from 'axios';
function Component01() {
function success() {
console.log("응답을 받는데 성공했습니다.");
}
function error() {
console.log("응답을 받았지만 문제가 생겼습니다.");
}
let sendRequest1 = () => {
axios.get("http://localhost:3001/get/simple/200").then(success).catch(error);
};
let sendRequest2 = () => {
axios.get("http://localhost:3001/get/simple/300").then(success).catch(error);
};
let sendRequest3 = () => {
axios.get("http://localhost:3001/get/simple/400").then(success).catch(error);
};
let sendRequest4 = () => {
axios.get("http://localhost:3001/get/simple/500").then(success).catch(error);
};
return(
<div>
<p>axios를 사용해 파라미터 없이 요청 보내기</p>
<div><button type="button" onClick={sendRequest1}>요청 보내고 상태 코드 200 으로 응답 받는 상황</button></div>
<div><button type="button" onClick={sendRequest2}>요청 보내고 상태 코드 300 으로 응답 받는 상황</button></div>
<div><button type="button" onClick={sendRequest3}>요청 보내고 상태 코드 400 으로 응답 받는 상황</button></div>
<div><button type="button" onClick={sendRequest4}>요청 보내고 상태 코드 500 으로 응답 받는 상황</button></div>
</div>
);
}
export default Component01;
<< 코드 설명 >>
(1). axios 를 사용하기 위해 import
(2). axios 로 요청을 보내고 200번대 상태 코드로 응답을 받았을 때 동작할 함수
(3). axios 로 요청을 보내고 300, 400, 500번대 상태 코드로 응답을 받았을 때 동작할 함수
(4). axios 로 요청을 보내는 함수
(5). 버튼을 클릭했을 때 적절한 함수를 호출 해 요청을 보냄
이제 리엑트 프로젝트를 실행시키고 이 컴포넌트를 출력해 각 버튼을 눌러보자
당연히 눈에 보이는 결과는 없음
왜? 위 코드 설명의 (2), (3) 을 다시 봐보면 응답을 받았을 때 console.log 로 출력하라고 되어있으므로...
브라우저 내 개발자 도구를 열고 [ console 패널 ] 로 가보자
서버가 상태 코드 200으로 응답했을 때만 success 함수가 호출되고 나머지 경우는 모두 error 함수가 호출된걸 알 수 있음
300, 400, 500 상태 코드는 특별한 경우이고 내가 서버에 대한 지식이 있거나 서버 개발자와 소통 해야되는 부분이므로 이제 언급하지 않겠음
const express = require('express');
const cors = require('cors');
const app = express();
const port = 3001;
app.use(cors());
app.get('/get/parameter', (req, res) => {
console.log("파라미터 있는 요청을 받았습니다.");
console.log("<< 클라이언트가 보낸 파라미터 >>");
console.log("name => " + req.query.name);
console.log("age => " + req.query.age);
console.log("tel => " + req.query.tel);
res.end();
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
<< 코드 설명 >>
(1). 클라이언트가 보낸 데이터는 req ( Request, 요청, 의 줄임말 ) 의 query 에 들어있음
query.(파라미터명) 으로 클라이언트가 보낸 데이터에 접근할 수 있음
노드 서버를 재시작 하자
이번에는 요청을 할 때 데이터를 담아서 요청을 보내보자
프로젝트 -> src -> chapter04 -> Component03.jsx 파일을 추가하고 아래 코드를 추가하자
import React from 'react';
import axios from 'axios';
function Component03() {
function success(response) {
console.log("응답을 받는데 성공했습니다.");
}
function error() {
console.log("응답을 받았지만 문제가 생겼습니다.");
}
const sendRequest1 = () => {
let data = {
name: "홍길동",
age: 23,
tel: "010-1111-1111"
};
let opt = {
params: data
}
axios.get("http://localhost:3001/get/parameter", opt).then(success).catch(error);
}
return(
<div>
<p>axios를 사용해 파라미터와 함께 요청 보내기</p>
<div><button type="button" onClick={sendRequest1}>파라미터(데이터)를 담아 요청을 보내는 상황</button></div>
</div>
);
}
export default Component03;
<< 코드 설명 >>
(1). 서버로 보낼 데이터
(2). 서버로 데이터를 보내기 위해 params 에 데이터를 담은 객체 생성
(3). 서버로 데이터를 보내기 위해 get 함수의 두 번째 인자로 opt 를 넣음
이 컴포넌트를 출력하고 버튼을 눌러보자
그 뒤 결과는 vs code 내 터미널에서 확인해야함
여기까지 GET 방식 요청을 통해
1. 서버로부터 상태 코드를 응답 받았을 때
2. 서버로부터 데이터를 응답 받았을 때
3. 서버에게 데이터를 보내는 방법
을 배웠음
이번에는 POST 방식 요청으로 서버에게 데이터를 보내는 방법을 알아보자
참고로 POST 방식 요청은 상태 코드를 응답 받았을 때, 데이터를 응답 받았을 때 처리는 GET 방식 요청과 완전히 동일함
const express = require('express');
const cors = require('cors');
const app = express();
const port = 3001;
app.use(cors());
app.post('/post/parameter', (req, res) => {
console.log("파라미터 있는 요청을 받았습니다.");
console.log(new Date().toLocaleString());
console.log("<< 클라이언트가 보낸 파라미터 >>");
console.log("name => " + req.query.name);
console.log("age => " + req.query.age);
console.log("tel => " + req.query.tel);
res.end();
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
<< 코드 설명 >>
(1). 클라이언트가 POST 방식으로 http://localhost/post/parameter 경로로 요청을 보냈을 때 처리하기 위한 코드
POST 방식으로 요청할 때 데이터를 담아 요청할 컴포넌트를 추가하자
프로젝트 -> src -> chapter04 -> Component04.jsx 파일을 추가하고 아래 코드를 추가하자
import React from 'react';
import axios from 'axios';
function Component04() {
function success(response) {
console.log("응답을 받는데 성공했습니다.");
}
function error() {
console.log("응답을 받았지만 문제가 생겼습니다.");
}
const sendRequest = () => {
let data = {
name: "홍길동",
age: 23,
tel: "010-1111-1111"
};
let opt = {
params: data
}
axios.post("http://localhost:3001/post/parameter", null, opt).then(success).catch(error);
}
return(
<div>
<p>axios를 사용해 파라미터와 함께 요청 보내기</p>
<div><button type="button" onClick={sendRequest}>파라미터(데이터)를 담아 요청을 보내는 상황</button></div>
</div>
);
}
export default Component04;
<< 코드 설명 >>
(1). 두 번째 인자 자리는 비워두고 세 번째 인자 자리에 보낼 데이터를 담아서 보낼 수 있음
리엑트는 부모 컴포넌트에서 map 함수로 자식 컴포넌트를 출력할 때 최소한의 동작만으로 빠르게 출력하기 위해 key 를 사용함
주소록 관리 프로젝트의 시작 ( https://codingaja.tistory.com/83 ) 에서 간단하게 언급만 했는데 "map 함수를 사용해 컴포넌트를 출력할 때 컴포넌트에 반드시 key를 전달해야하며 key는 컴포넌트 간에 구분할 수 있는 유일한 값이어야함" 라고 했음
다음과 같은 주소록 페이지가 되도록 주소 정보를 추가하자
이 상태의 웹 페이지를 시각적인 컴포넌트 트리로 그려보자
AddressList 컴포넌트의 addressList 배열 안에는 address가 서울1 ~ 서울5인 데이터들이 들어있고 이를 통해 Address 컴포넌트가 만들어짐
여기까진 우리가 알고 있는 당연한 상황임
여기서 address가 서울3인 3번째 주소 정보의 [ 삭제 ] 버튼을 누른 상황이라고 해보자
그러면 address가 서울3인 Address 컴포넌트에서 AddressList 부모 컴포넌트로 삭제 시그널을 보내 useEffect 훅이 splice 함수를 사용해 addressList의 2번 인덱스(3번째) 주소를 삭제함
이때의 addressList의 상황을 보면 아래와 같음
이제 컴포넌트가 어떻게 생성될까?
다음과 같이 생성됨
리엑트는 기존의 Address 컴포넌트들의 key와 새로운 Address 컴포넌트들의 key를 비교해 key가 다른 컴포넌트만 교체함
기존의 Address 컴포넌트들 중에서 key가 4인 Address 컴포넌트가 있었는데 새로운 Address 컴포넌트들 중에서는 key가 4인 Address 컴포넌트가 없으므로 그래서 화면 상에서는 마지막 컴포넌트가 지워지는 것
결국 addressList 배열 상에서는 지우고자 하는 주소 정보가 지워졌지만 리엑트의 컴포넌트 갱신 방식 때문에 잘못된 데이터가 지워져 보이는 것
address는 주소 정보를 저장할 값이지만 setAddress는 setter 함수라는 점에 유의하자
JS는 함수가 1급 객체이기 때문에 이와 같이 함수를 전달할 수도 있음
자식 컴포넌트로 값들을 보내기 위해 { } 로 묶었다는 점에도 유의하자
address는 AddressList 컴포넌트에서 사용하고 setAddress는 AddressAdd 컴포넌트에서 사용함
(5). AddressMng 부모 컴포넌트가 전달한 setter 를 꺼내기 위해 공용 변수를 import함
(6). 공용 변수에 들어있는 setter를 꺼내기 위해 우선 useContext 훅을 사용함
conset setAddress = useContext(AddressContext); 만 하게 되면 setAddress 변수에 address 값을 갖고 있는 변수와 setter 함수가 모두 저장됨, 이와 같이 했다면 setAddress.setAddress(address); 로 해야하기에 좀 더 편하게 사용하기 위해 공용 변수가 갖고 있는 setter 함수만 setAddressd 변수에 저장함
(7). 부모 컴포넌트가 공용 변수에 담아서 보내준 setter 를 사용해서 주소 정보 저장