코로 넘어져도 헤딩만 하면 그만
26일차~30일차 스터디 본문
이번 주에 학습한 것: ajax, fetch, promise, 리액트
비동기 처리 방법과 리액트에 관해 배워보는 한 주였습니다. 비동기 개념부터 시작해서 리액트를 적용하려니 정말 만만치 않더군요. 그렇게 수업하던 중 자연히 생겨난 몇몇 의문을 스터디 발표를 준비하며 알아보는 시간을 가졌습니다.
🎈1. Ajax, Axios, fetch. 그래서... 뭐가 다릅니까?
Ajax, Axios, fetch 이 셋은 클라이언트와 서버간의 데이터를 주고 받기 위한 비동기 통신 기술로 자주 비교됩니다. 유사점이 있는 만큼 차이점에 주목해야겠죠. 비동기를 격파하기 위해 이 셋에 관해 조금 더 살펴보기로 했습니다.
(1) Ajax?
Ajax(Asynchronous JavaScript And XML)는 JavaScript를 이용해 클라이언트와 서버 간의 데이터를 주고 받는 비동기 HTTP 통신 기술입니다. 초기에는 XML을 사용했지만, 이제는 JSON 데이터 형식을 많이 사용합니다. 그러나 여전히 이름에는 XML이 들어가 있죠. 서버와 비동기적으로 통신하며, 전체 웹페이지를 매번 새롭게 불러올 것 없이 필요한 부분만 갱신할 수 있게 해주는 기술이라고 이해하면 될 것 같네요. 당연히 비동기가 핵심 키워드고요.
초반에 Ajax는 XMLHttpRequest API(XHR)객체를 사용했습니다. XHR은 AJAX 요청을 생성하는 JavaScript API였죠. Ajax는 jQuery를 통해서 쉽게 구현하지만, 역설적으로 jQuery를 사용하지 않으면 코드가 비직관적이며 어려워진다는 단점을 가졌습니다. 여기서 잠깐?! jQuery와 Ajax가 서로 일치하는 개념은 아닙니다. 음... 정확히 말하자면 Ajax가 jQuery에게 도움을 많이 받았다고 합시다. XHR을 쓸 때 지저분하던 코드를 jQuery를 사용하면 훨씬 간결하게 쓸 수 있었거든요. 그러니 자연히 함께 묶여 비슷하게 취급되었죠.
그러나 사실 Ajax라는 이름은 2005년 구글에 의해 등장했으며, 서버에 필요한 데이터만 비동기적으로 요청하는 XHR은 이미 1999년부터 쓰였답니다. Ajax는 XHR을 포함하면서 더 나아가 비동기 요청 처리와 관련된 기술 전체를 통칭하는 단어로 등장합니다. Ajax와 jQuery가 동일하지 않되 Ajax가 jQuery에게 많이 도움 받았다고 이해하면 좋겠네요.
또 XHR을 사용하던 시절의 Ajax는 Promise 기반이 아닙니다. Axios와 fetch는 Promise 기반이니, 이들과는 확연한 차이를 갖습니다. Error, Success, Complete의 상태를 통해 실행 흐름을 조절 가능합니다.
순수한 Ajax 사용한 코드 예시
// use Ajax without Jquery
function reqListener (e) {
console.log(e.currentTarget.response);
}
var oReq = new XMLHttpRequest();
var serverAddress = "https://jsonplaceholder.typicode.com/posts";
oReq.addEventListener("load", reqListener);
oReq.open("GET", serverAddress);
oReq.send();
jQuery를 사용한 예시
// use Ajax with Jquery
var serverAddress = 'https://jsonplaceholder.typicode.com/posts';
// jQuery의 .get 메소드 사용
$.ajax({
url: ,
type: 'GET',
success: function onData (data) {
console.log(data);
},
error: function onError (error) {
console.error(error);
}
});
정말 코드가 깔끔합니다. 왜 Ajax를 쓰던 개발자들이 흔쾌히 jQuery의 힘을 빌렸는지 알 수 있지요? 이처럼 jQeury를 이용한 비동기 처리 방식은 점차 대중적이 되어서, Ajax === jQuery문법으로 아는 사람들도 생겨납니다.
이처럼 이전에도 Ajax를 통해 비동기 요청을 처리할 수는 있었습니다. 하지만 jQuery에 의존하지 않는 이상 지저분한 XHR객체(XML HTTP Request)를 사용해야 했습니다. 이를 개선하고 싶은 사람들이 생겨나는 건 당연한 수순이었죠. 그 결과 XHR에 대한 보완으로, HTTP요청에 최적화 되고 추상화가 잘 되어있는 API들이 생성됩니다. 그것이 바로 지금부터 소개할 fetch와 Axios입니다.
- fetch?
앞서 설명했듯이 Ajax는 초기 XMLHttpRequest API(XHR)를 이용해야 했습니다. 그러나 더럽게 복잡한 방식에 불만을 가진 사람들이 jQuery에 의존하며 더 쉽게 비동기 요청과 처리를 구현하기 시작했습니다. 하지만 fetch API가 ES6 표준에서 새로 등장하면서 fetch를 통해 구현하는 것이 이젠 일반적인 방법이 되었습니다. 한마디로 기존의 Ajax가 fetch로 더 쉽게 사용할 수 있게 개선되었다고 할 수 있습니다.
fetch는 ES6부터 도입된 JS 내장 라이브러리입니다. Promise 기반으로 만들어졌기 때문에 데이터 다루기도 쉽습니다. ...내장 라이브러리요? 그렇다면 별도의 설치와 import가 필요 없겠군요. 설치도 필요 없다니 편하게 들리겠지만 fetch에도 아쉬운 점이 몇몇 존재합니다.
네트워크 에러 발생 시에 response timeout이 없어서 기다려야 하며, 데이터를 받아올 때마다 json 형태로 바꿔줘야 합니다. 또한 Axios에 비해 기능이 여러 부분에서 부족합니다.
가령 백엔드에서 데이터를 제대로 처리 못한 오류 시 400, 500번대의 상태 코드를 보낸다고 해봅시다. fetch는 이 경우에도 200번대 상태 코드의 성공과 같이 결과를 then으로 받아옵니다. 성공과 오류가 then으로 섞이는 문제가 발생하는 것입니다. 반면 Axios는 상태 코드가 200대로 성공이 뜬 경우에만 then으로 들어옵니다. 200대가 아니라면 catch로 들어오기 때문에 에러를 핸들링하기 쉽죠.
참고:
https://10000cow.tistory.com/entry/React-axios를-사용하는-이유에-대해-fetch-API-vs-axios
fetch는 아래와 같은 방식으로 사용합니다.
fetch("https://localhost:3000/user/post", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
id: "asd123",
description: "hello world",
}),
}).then((response) => console.log(response));
- Axios?
Axios는 Node.js와 브라우저를 위한 Promise API를 활용하는 HTTP 통신 라이브러리입니다. 비동기로 HTTP 통신이 가능하며, Promise 객체를 반환해주기 때문에 응답 데이터를 다루기 쉽습니다.
리액트를 사용한다면 fetch보다는 Axios가 많이 선호됩니다.
axios({
method: 'post',
url: 'https://localhost:3000/user',
data: {
userFirstName: 'Lee',
userLastName: 'Yang'
userId: 'yl234'
}
}).then((response) => console.log(response));
위와 같이 쓰는 Axios는 사용하기 전 npm install axios로 설치 해야 하는 번거로운 점을 가집니다.
그러나 fetch에는 없는 기능인 response timeout 처리 방법이 존재하고, request를 취소할 수 있으며, fetch처럼 Promise 기반이기 때문에 데이터 다루기가 편리합니다. 또한 JSON 파일은 자동으로 내부에서 바꿔주며 fetch보다 크로스 브라우징에서 우수해 구형 브라우저 지원을 해준다는 것이 장점입니다.
✨결론:
- 간단한 통신의 경우 fetch를 사용해도 좋으나 기능이 더 많이 필요하다면 Axios를 사용하는 게 좋습니다. Axios에서 쉽게 구현이 가능한 기능인데, fetch에선 기본 제공이 되지 않거나 추가 로직 구현이 필요한 것들도 있기 때문입니다.
- 그러나 react-native와 같이 안정화 되지 못한 프레임워크에서는 내장된 fetch를 쓰는 게 더 나을 수도 있습니다.
[개발상식] Ajax와 Axios 그리고 fetch
여러분들이 프로젝트를 진행하다보면 클라이언트와 서버 간 데이터를 주고받기 위해 HTTP 통신을 사용하게될겁니다. 주로 어떤것을 사용하시나요? 또, 그것에 대해 얼마나 알고계시나요? 저와
velog.io
https://www.geeksforgeeks.org/difference-between-fetch-and-axios-js-for-making-http-requests/
Difference between Fetch and Axios.js for making http requests - GeeksforGeeks
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
www.geeksforgeeks.org
🎈2. JSON파일이 그래서 뭡니까?
JSON(JavaScript Object Notation)은 JavaScript 객체와 확실히 구분됩니다.
JSON은 'JS 객체 표기법에서 파생된, 데이터를 경량으로 쉽게 공유하기 위한 표현 방법'입니다. JS 객체와 비슷하게 생겼지만 특정 언어에 종속된 것이 아니라서 대부분의 프로그래밍 언어에서는 JSON 파일을 핸들링하는 라이브러리를 제공합니다. 따라서 우리는 자바스크립트 객체로 HTTP 통신을 한다고 하지 않고, JSON으로 데이터를 주고 받는다고 명시해야 합니다.
또한 프론트엔드에서 JSON 데이터를 가공하려면 객체로 바꿔주는 작업을 해줘야 하고, 백엔드에서 JSON으로 데이터를 보내기 위해서도 바꿔주어야 합니다. 즉 JSON 텍스트 → JS 객체는 JSON.parse() 메소드로, JS 객체 → JSON 텍스트는 JSON.stringify() 메소드로 바꿔주는 과정이 필요합니다.
줄임말처럼 JSON의 기본 문법은 JS객체에서 온 것이 맞지만 약간의 다른 점을 가집니다.
{
"name":"Jack",
"age":30,
"contactNumbers":[
{
"type":"Home",
"number":"123 123-123"
},
{
"type":"Office",
"number":"321 321-321"
}
],
"spouse":null,
"favoriteSports":[
"Football",
"Cricket"
]
}
JS 객체처럼 key와 value를 갖고 있지만, JSON은 모든 키를 "" 내부에 묶어야 합니다. 또한 데이터를 쉼표로 나열하며, 함수를 값으로 할당할 수 없습니다.
JSON 내부에서는 주석을 쓸 수 없다는 점도 자칫 실수하기 쉬운 부분입니다.
“저는 JSON에서 주석을 없앴습니다. 사람들이 해석 지시 사항들을 표기하기 위해 주석을 이용하는 것을 본 이후로요. 이런 식으로 사용하게 된다면 상호 호환성을 방해하게 되기 때문입니다.” - 창시자, 더글라스 크록포드 曰
기존까지는 XML이 데이터 교환을 위해 널리 사용되었습니다. 하지만 JSON이 더 명확하며 덜 복잡한 양식을 제공했고, 동일한 데이터도 짧게 제공하여 전송 용량을 줄였기 때문에 요즘은 JSON을 많이 씁니다.
그러니 JSON을 쓸 때에는
- JSON !== JS객체
- JS객체와 달리 key를 큰따옴표로 묶어야 하며, 주석을 쓸 수 없고, 함수가 올 수 없다
- XML보다 경량이라 요즘은 더 애용되고 있다
- 데이터 전송을 위해서 주어진 JS 객체를 JSON.stringify()를 사용해 JSON으로 인코딩 된 '문자열'로 바꿔줘야 한다
는 점을 잊지 않도록 해야 할 것입니다.
참고:
https://ko.javascript.info/json
JSON과 메서드
ko.javascript.info
[개발상식] JSON과 JavaScript Object의 차이점
안녕하세요. 김용성입니다.정말 비슷하게 생겨먹은 녀석들이 존재합니다. 바로 흔히들 사용하는 JSON(JavaScript Object Notation)과 JavaScript Object인데요. 이 둘 간에는 어떤 차이점이 있을까요?
velog.io
🎈3. Promise.allsettled? Promise.race?
Promise에는 5가지 정적 메서드가 존재합니다.
상황에 따라 알맞은 메서드를 사용하기 위해 각각 사용법을 알고 있는 것이 좋겠죠. 수업 중에는 세 가지에 대해서만 배웠지만, 나머지 메서드들도 보고 익숙해지려고 합니다.
1) Promise.all
let promise = Promise.all([...promises...]);
요소 전체가 프라미스인 배열을 받고, 새로운 프라미스를 반환합니다.
Promise.all의 특징으로, 전달되는 프라미스 중 하나라도 거부되면 반환하는 프라미스는 에러와 함께 전체 거부된다는 점이 있습니다. 즉! 프라미스가 하나라도 거부되면 Promise.all은 즉시 거부되고 배열에 저장된 다른 프라미스의 결과는 완전히 무시됩니다. 다른 프라미스가 처리되긴 하지만 결과들은 무시되는 것입니다.
2) Promise.allsettled
Promise.all은 프라미스가 하나라도 거절되면 전체를 거절합니다. 그러나 Promise.allsettled는 모든 프라미스가 처리될 때까지 기다려줍니다. 각각 반환되는 배열은 다음과 같은 요소를 갖습니다.
- 응답이 성공할 경우 – {status:"fulfilled", value:result}
- 에러가 발생한 경우 – {status:"rejected", reason:error}
하나가 실패해도 다른 요청 결과는 필요할 때 allsettled를 쓸 수 있습니다. 결과로는 각 프라미스의 상태와 값 또는 에러를 받을 수 있습니다.
단, 추가된 지 얼마 되지 않은 문법이기 때문에 구식 브라우저에서 쓸 때는 '폴리필' 이라는 것을 구현해주면 됩니다.
3. Promise.race
Promise.race는 Promise.all과 비슷하지만, 가장 먼저 처리되는 프라미스의 결과(혹은 에러)를 반환합니다. 가장 먼저 처리되는 결과가 값이 되는 것이죠. '경주race처럼 승자가 나타난 순간' 다른 결과는 전부 무시됩니다.
- 이하 resolve와 reject는 async/await가 나타난 뒤 거의 사용하지 않는다고 합니다. 참고만 하면 될 것 같습니다.-
4. Promise.resolve
Promise.resolve(value)는 결괏값이 value인 이행 상태 프라미스를 생성합니다. 함수가 프라미스를 반환하도록 해야 할 때 사용할 수 있습니다.
5. Promise.reject
Promise.reject(error)는 결괏값이 error인 거부 상태 프라미스를 생성합니다.
🐥실무에서는 Promise.all을 가장 많이 사용한다고 하니 참고하시면 될 것 같습니다.
출처: https://ko.javascript.info/promise-api
프라미스 API
ko.javascript.info
🎈4. 리액트에서 조건문은?
리액트에서 개발을 할 때에는 if문이나 switch문을 사용할 때 제한이 있습니다. 함수의 return되는 부분 내(JSX문)에서 조건식을 사용할 수 없단 뜻이죠. 따라서 && 연산자, 혹은 삼항 연산자가 많이 사용됩니다.
1) 컴포넌트 안에서 쓰는 if/else
return()의 JSX 내부에서는 자바스크립트 if문을 사용할 수 없습니다. <p> if(){}~~~ </p> 이런 식이 불가능하다는 뜻이죠.
따라서 if문을 반드시 쓰고 싶다면 return문의 바깥으로 빼내는 편이 낫습니다. 아래와 같이 말이죠.
function Component() {
if ( true ) {
return <p>참이면 보여줄 HTML</p>;
} else {
return null;
}
}
else는 생략도 가능합니다. JS 함수 내에선 return을 만나는 순간 그 아래의 코드는 더이상 실행하지 않기 때문입니다.
function Component() {
if ( true ) {
return <p>참이면 보여줄 HTML</p>;
}
return null;
}
혹은 즉시실행 함수를 만들어서 if문은 그 내부에 작성해주고 JSX문 내부에는 함수만 넣어주는 식으로 쓸 수 있습니다.
물론 이 방법들은 그렇게 효과적인 방법은 아닙니다. 번거롭고, 코드가 좀 지저분해지죠.
2) 삼항연산자
조건 ? 조건이 참일때 실행할 코드 : 거짓일 때 실행할 코드
위와 같이 쓰는 삼항연산자는 if와 다르게 JSX 내부에서도 실행 가능하다는 장점을 갖습니다. 또한 중첩 사용도 가능합니다. 다만 코드가 지저분해지지 않도록 주의해주어야 합니다.
function Component() {
return (
<div>
{
1 === 1
? <p>참이면 보여줄 HTML</p>
: null
}
</div>
)
}
3) && 연산자 (단축 평가 조건식)
우리가 기존까지 쓰던 &&연산자는 조건문에서 두 조건을 모두 만족하는 경우 true를 반환하는 식으로 쓰였습니다. 그러나 리액트에서는 조건문처럼 &&를 사용할 수 있습니다.
아래 코드를 볼까요? && 앞의 조건이 true로 충족할 때에만 && 뒷부분이 남습니다. 조건이 false일 때는 렌더링을 하지 않습니다. 따라서 true 조건일 때에만 어떤 작업을 하고 싶을 때 이 연산자를 쓰면 좋을 것 같네요.
function Component() {
return (
<div>
{ 1 === 1 && <p>참이면 보여줄 HTML</p> }
</div>
)
}
참고:
https://codingapple.com/unit/react-if-else-patterns-enum-switch-case/
리액트에서 자주쓰는 if문 작성패턴 5개 - 코딩애플 온라인 강좌
(리액트 강좌 전체 메뉴) 딱히 설명할 부분이 없어서 글로 진행합니다. 지금까지 JSX 이용해서 html을 작성하고 있는데 if문을 써서 조건부로 html을 보여주고 싶을 때가 매우 많습니다. 지금까지는
codingapple.com
이번 주의 단어
jQuery : JS를 생산성 있게 사용하도록 단순화시킨 오픈 소스 기반의 자바스크립트 라이브러리.
response timeout: 요청시 프로그램이 특정한 시간 내에 성공적으로 수행되지 않아서 진행이 자동적으로 중단되는 것으로, 응답을 무한정 기다릴 수 없기 때문에 기다릴 시간을 정해주어야 한다.
'CODE STATES 44' 카테고리의 다른 글
Tree UI를 재귀함수로 만들기 (0) | 2023.04.12 |
---|---|
Section 2 회고 (1) | 2023.04.10 |
REST API, Open API (0) | 2023.03.29 |
HTTP, 네트워크 기초에 대한 글 (0) | 2023.03.29 |
React를 잘근잘근 씹으며 만드는 Twittler(트0터 짭...) (0) | 2023.03.27 |