우선 과제 예시 사이트에서는 todolist에 부여되는 id를 만드는 것을 패키지를 이용해서 하였다. 원래 redux 모듈안에 변수를 만들어서 id값을 만들었는데, 매니저님께서 다른방법을 쓰라고 하셔서 다른 방법을 생각중이었다. 다른 패키지 도움 없이 만드려고 하니까 여러가지 상황을 고려할게 많아져서 머리가 아파졌다. 특히나 문제는 detail창에 들어 갔다 나오면 state값이 초기값으로 바뀌어 중복값이 나오는 것이 문제.
머리를 뽑다가 같은 팀원분과 서로 문제를 공유했다. 팀원분의 문제는 이미 내가 시행착오를 겪었던 문제라서 금방 해결이 되었고, 팀원분도 지금 내문제를 해결했던 문제라서 알려주셨다.
방법은 옵셔널체이닝을 사용해서 todo를 저장하는 dispatch시에 todos 배열이 undifined이나 null이라면 그 값을 id에 넣지 말고 0을 넣어라, 근데 배열안에 값이 존재한다면 배열의 마지목요소의 id값에 1을 더해서 id를 만드는 방법을 이용했다.
그런데 또다시 발생한 문제는 detail.jsx, 디테일 페이지에서 생긴 문제이다. useEffect안에서url에서 가져온 id값으로dispatch를 하여 todo객체를 가져와 그 정보를 보여주는 페이지인데, 내일은 이 문제 해결법을 생각해봐야겠다.
Styled Component
매니저님도 잘쓰면 좋다고 하시고, 나도 처음써보기 때문에 많이 미숙한 것같아 제대로된 사용법을 익히고자 정리했다.
redux를 배우면서 엄청난 편리함을 느꼈다. 하나하나 props로 내려주던 때와 달리 module을 하나만 만들어놓으면 저장된 값을 가져오기만 하면되니 정리도 쉽고 너무 편했다.
데이터를 받는 Form 컴포넌트에서 모든 기능과 state를 관리했던 때는 Form컴포넌트 파일이 너무 복잡해져서 관리하기가 어렵고 보기도 힘들었는데, 왜 redux를 사용하는지 알게되었다.
또 리덕스를 쓰기전에는 파일에 코드가 길어지니까 관리가 힘들어서 컴포넌트를 세분화하기가 애매하다고 느꼈었는데, 리덕스를 사용하니 이정도로 가져다쓰는게 편하면 컴포넌트를 더 세분화할만 하겠는데...?라는 생각이 들었다.
이번주차의 KEYWORD
DOM(The Document Object Model)
DOM은 HTML, XML 문서의 프로그래밍 interface이다. DOM은 문서의 구조화된 표현(structured representation)을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다. DOM 은 nodes와 objects로 문서를 표현한다. 이들은 웹 페이지를 스크립트 또는 프로그래밍 언어들에서 사용될 수 있게 연결시켜주는 역할을 담당한다.
즉 웹페이지에서 우리가 배우는 자바스크립트라는 프로그래밍 언어로 요소들을 제어하는데 DOM이 사용된다는 뜻!
HTML의 보이는 요소들을 자바스크립트로 변화를 주는 것을 '동적으로' 무언가를 바꿔준다는 표현을 쓴다.
const title = document.getElementById("title");
title.textContent = "바뀐 텍스트";
이렇게 자바스크립트를 통해서 DOM요소를 조작할 수 있다.
여기서 document.getElementById와 textContent는 자바스크립트의 요소가 아니다.
이를 알 수 있는 방법은 브라우저와 Node.js 환경에서 console.log(document)를 찍어보면 브라우저에서는 document객체가 출력되지만 Node.js에서는 오류가 뜨는 것을 확인 할 수 있다.
이 의미는 document 객체는 자바스크립트 자체의 요소가 아니라 브라우저 환경에서 제공되는 것!
이 document객체는 브라우저에서 제공하는 window객체의 한 요소이다. 이 window.document객체를 DOM이라고 부르는 것이다.
우리가 작성한 HTML 파일을 브라우저에서 보고 parsing하여 DOM으로 만들어 주는것이고, 이 DOM은 트리 형태로 만들어진다. 그리고 이 요소 하나하나를 Node라고 부른다.
그리고 자바스크립트로 웹페이지의 요소를 제어할 수 잇는 건 이것들 하나하나가 API이기 때문이다.
document에 getElementById라는 API가 있고 DOM내에서 주어진 id인 "title"을 가진 노드, h1을 가져와서 h1노드의 속성인 textContent를 이용하여 텍스트 값이 바뀔 수 있도록 한 것이다.
그리고 이 노드들은 상속 구조를 가지게 된다. DOM 트리와는 다른것, 요소가 어느 범주에 속하는지를 나타냄.
보면 h1태그는 HTMLHeadingElement에 속하고 이것은 HTMLElement => Element=> Node=>EventTarget 순으로 속하는 걸 볼 수 있다.
그리고 다른 모든 요소들도 EventTarget이라는 공통 범주안에 속하는 모습을 볼 수 있다.
이걸 다시 확인해보면
const title = document.getElementById("title");
title.textContent = "바뀐 텍스트";
getElementById는 document의 기능인것을 볼 수 있고, textContent는 MDN에서 확인 했을 때 Node의 기능인 것을 알 수 있다.
그럼 제일 상위에 EventTarget은 모든 요소들이 다 쓸 수 있다는 건데, 뭐하는 애인가?
말그대로 클릭이나, 드래그, 키보드 입력등과같은 어떤 이벤트들의 대상이 된다는 것이다.
대표적으로 EventTarget의 메서드에는 우리가 잘 아는 addEventListener가 있다. 이 기능은 EventTarget의 기능이기 때문에 EventTarget 하위의 모든 요소들이 상속받아 사용이 가능한 것이다.
번외로 DOM말고 BOM, Browser Object Model이 있는데, 이것은 브라우저에서 일어날 일들을 프로그래밍 할 수 있도록 제공되는 기능이다.
이렇게 브라우저에서 제공하는 모든 것을 통틀어 WEB API라고 한다.
서버리스(Severless)
서버리스는 서버를 사용하지 않는다는 의미가 아니라, 실제 의미는 클라우드 서비스 공급자가 서버를 관리, 실행하며, 특정 이벤트가 있을 때 클라우드의 서버를 이용하거나 서비스 할 어플리케이션을 동작시키는 것입니다. 이를 통해 사용자(개발자)는 서버 관리에서 완전히 자유로워지며 실제 구현해야 할 기능에 더 집중할 수 있게 됩니다.
서버리스는 보통 '서버리스 컴퓨팅' 또는 '서버리스 아키텍처'로 불립니다. 서버리스 개념은 어플리케이션 관점에서 BaaS(Backend as a Service)와 FaaS(Function as a Service)로 나누어 살펴보면 이해가 더 용이합니다.
Baas
BaaS는 단일 웹페이지나 모바일 앱 기반의 서비스에서 필요한 서버 기능들을 사용하기 위해 이용하는 써드파티(Third Party) 어플리케이션이나 클라우드 서비스를 일컫습니다. 쉽게 말해 어플리케이션 개발 시 요구되는 복잡한 백앤드(Back-End) 기능들을 사용자(개발자)가 직접 개발하지 않고 클라우드 공급자가 제공하는 서비스를 이용해 쉽고 안정적으로 구현하는 것입니다. 주된 사용 대상이 모바일 앱과 웹 앱(WebApp)이다 보니 MBaaS(Mobile Backend as a Service)라 불리는 시장이 활성화 되는 추세입니다. 클라우드 데이터베이스 서비스인 Firebase나 클라우드 인증 서비스인 Auth0가 BaaS에 해당합니다.
Faas
BaaS가 클라우드 서비스 공급자가 제공하는 서버 기능을 단순하게 이용한다면 이와 달리 FaaS는 사용자가 쓸 기능을 함수 단위로 나누어 구현하고 이를 서비스하는 형태입니다. FaaS는 Event-Driven 아키텍처를 구현하는데 적합하며 사용자가 원하는 기능을 미리 작성해놓고 특정 이벤트(예를 들어 HTTP Request, API 호출, 특정 조건 등)에 의해 실행됩니다. 이때 서버는 계속 대기하면서 이벤트를 기다리지 않고 이벤트가 발생할 때마다 실행됩니다. 비용은 서버가 실행된 횟수와 시간(밀리세컨드. 1,000분의 1초)에 따라 산정됩니다. FaaS를 구현한 대표적인 서비스로 AWS의 Lambda, 마이크로소프트의 Azure Functions, 구글의 Google Cloud Functions 등이 있습니다.
서버리스의 장점
첫째, 운영 비용 절감 효과를 들 수 있습니다. IaaS나 PaaS와 같이 상시 운영 중인 서버와 달리 요청에 따라 호출되어 처리되기 때문에 유휴 자원이 발생하지 않습니다.
둘째, 서버리스는 기존 클라우드 서비스보다 더 유연한 확장성을 제공합니다. FaaS의 경우 일반적인 클라우드 서비스와 같이 특정 조건(예를 들어 CPU, RAM 임계치 도달과 같은)에 따라 확장되는 방식이 아닌, 호출될 때마다 새로운 인스턴스가 기동되어 동작하기 때문에 특정 조건을 설정하지 않아도 급격한 트래픽 변화에 유연한 대응이 가능합니다.
셋째, 기능이 함수 단위로 개발되기 때문에 서비스를 빠르고 간단하게 출시할 수 있습니다.
단점
첫째, 빠른 응답이 필요한 제품의 경우 서버리스로의 전환은 부적합할 수 있습니다. 이는 실행되는 함수가 호출되기 위해 컨테이너가 실행되는 대기 시간(콜드스타트, Cold-Start)이 존재하기 때문인데 서버가 항시 기동되고 있지 않은 서버리스의 특징에 기인합니다.
둘째, 무상태(Stateless)적인 기능으로 구현되어야 합니다. 하나의 작은 기능으로 나뉘어진 함수들은 요청마다 새로 기동되어 호출되기 때문에 전후 상태를 공유할 수 없습니다. 또한 변수와 데이터의 공유가 불가능하며, 데이터를 로컬 스토리지에서 읽고 쓸 수 없습니다. (이는 서버리스 벤더에 따라 추가 서비스를 통해 극복이 가능하지만, AWS S3, Azure Storage등 일반적인 서버리스는 불가능합니다.)
셋째, 서버리스 서비스 벤더가 제한을 두는 사항은 그대로 수용해야 합니다. 함수 내에서 사용할 수 있는 최대 메모리, 최대 처리 가능 시간 등의 제약이 그것입니다. 이에 따라 큰 기능을 잘게 나누어 구현해야 합니다. 이를 준수하지 않고서는 서버리스로 이전할 수 없습니다.
프로비저닝
프로비저닝(provisioning)은 사용자의 요구에 맞게 시스템 자원을 할당, 배치, 배포해 두었다가 필요 시 시스템을 즉시 사용할 수 있는 상태로 미리 준비해 두는 것을 말한다.
2. 좋았던 점
새로운걸 배워서 적용할때마다 사용이유를 체감할 수 있어서 좋았....다?
3. 개선할점 / 아쉬운점.
React lifecycle에 관한 개념
주차 목표를 먼저 확실히 공부하자(전역상태관리의 필요성, 비동기 처리방법)
좀 더 생각하면서 코딩하기, (코드의 이유를? 생각하면서 짜기, 지난주차 수정하기 기능을 추가할때 아무생각 없이 props를 내리고 state를 관리했던게 아쉽다. 분명 좀 더 깔끔하고 좋은 방법이 있었을 텐데.)
내년엔 이맘때에 놀이공원은 너무 힘들것 같고 ㅋㅋ 어디 한적하고 경관 좋은 곳으로 여행가고 싶다...
또 과제코드를 팀원들끼리 리뷰를 했는데, 각자 코드들이 다 다르다보니 흥미로웠다. useRef를 이럴때 사용하는구나, 이런식으로 쓰면 코드가 간결해지고 알아보기도 쉽구나... 등등 배울것도 많았다.
조언도 서로 해줬는데, 내가 추가한 기능에서 todolist 수정기능이 있다. todolist를 수정할 때, 나는 배열에서 선택된 객체를 삭제하고 다시 수정된 값을 넣어주는 방식으로 했다. 그런데 원래 있는 데이터에서 수정을 할 수도 있지 않았냐는 질문을 들었을때, 그렇게 하는것도 맞다는 생각이 들었다.
약간 결이 다른 수정이라고 생각한다.
그 생각을 한 것 같긴 한데, 그 당시에 그렇게 하려면 코드가 꼬일것 같아 내가 이해하기 좀 더 쉬운 방법으로 선택을 했던것 같다.
근데 다시 생각해보니 map함수를 이용하면 쉽게 가능 할 것 같기도... 나중에 고쳐봐야겠다.
어쨌든 이번에도 좋은 팀원들을 만나서 잘 마무리 된것 같고, 다음 발제를 위한 준비를 해야겠다.
프로퍼티 Getter와 Setter
객체의 프로퍼티는 두 종류로 나뉜다.
첫번째 종류는 data Property, 지금까지 사용한 모든 프로퍼티
두번째는 접근자 프로퍼티(accessor property)라 불리는 새로운 종류의 프로퍼티. 접근자 프로퍼티의 본질은 함수이고, 이 함수는 값을 획득(get)하고 설정(set)하는 역할을 담당합니다. 그런데 외부 코드에서는 함수가 아닌 일반적인 프로퍼티처럼 보인다.
각각 객체 리터럴 안에서 get과 set으로 나타낼 수 있다.
let obj = {
getpropName() {
// getter, obj.propName을 실행할 때 실행되는 코드
},
setpropName(value) {
// setter, obj.propName = value를 실행할 때 실행되는 코드
}
};
getter사용시
let user = {
name: "John",
surname: "Smith",
getfullName() {
return`${this.name}${this.surname}`;
}
};
alert(user.fullName); // John Smith
이렇게 바깥코드에서 접근자 프로퍼티를 일반 프로퍼티처럼 사용할 수 있고,
즉 함수처럼 user.fullName() 이 아니라 일반 프로퍼티 user.fullName 이렇게 사용하여 프로퍼티 값을 얻을 수 있다.
그러나 getter 메서드만 있는경우
let user = {
getfullName() {
return`...`;
}
};
user.fullName = "Test"; // Error (프로퍼티에 getter 메서드만 있어서 에러가 발생합니다.)
getter 메서드에 할당하려하면 위 처럼 에러가 발생한다.
setter 메서드를 추가해서 에러가 발생하지 않도록 할 수 있다.
let user = {
name: "John",
surname: "Smith",
getfullName() {
return`${this.name}${this.surname}`;
},
setfullName(value) {
[this.name, this.surname] = value.split(" ");
}
};
// 주어진 값을 사용해 set fullName이 실행됩니다.
user.fullName = "Alice Cooper";
alert(user.name); // Alice
alert(user.surname); // Cooper
이렇게 fullName 프로퍼티로 다른 값을 할당해주어도 에러가 발생하지 않고 제대로 바뀐값이 출력되는것을 볼 수 있다.
아무래도 이렇게 먼저 과제를 다 해서 시간이 있을 때, 좀 더 체계적으로 나아갈 수 있는 방향을 생각해보는게 좋을 것 같다. 나름 혼자서 필요한걸 배워보겠다고 이것저것 찾아보면서 공부했지만. 최소한 항해에서 만큼은 이 방향이 맞는지도, 효율적인지 판단하기 어렵다. 매주 과제가 있고, 그 과제를 빠르게 해내야 다음을 준비할 시간이 있기 때문에, 이런 부분을 좀더 매니저님께 여쭤봐야겠다.
React Hook
useEffect 간단 설명
import { useState, useEffect } from"react";
functionTest() {
const [counter, setValue] = useState(0);
const [keyword, setKeyword] = useState("");
const onClick = () => setValue((prev) => prev + 1);
const onChange = (event) => setKeyword(event.target.value);
console.log("i run all the time");
// 첫번째 렌더에만 실행
useEffect(() => {
console.log("I run only once");
}, []);
//keyword, counter 변화시에 실행
useEffect(() => {
console.log("I run when 'counter' and 'keyword' changes");
}, [keyword, counter]);
return (
<div><inputvalue={keyword}type="text"onChange={onChange}placeholder="Search here..."
/><h1>{counter}</h1><buttononClick={onClick}>click me</button></div>
);
}
exportdefault Test;
최초 렌더시 useEffect와 console.log가 작동된다.
input에 글자를 쳤을 때, keyword와 counter값의 변화를 알아차리는useEffect가 작동되어 "I run when counter and keyword changes" 가 나오는것을 볼 수 있다.
또한 어떠한 조건도 걸어 놓지 않은 console.log("i run all the time")도 작동된다.
그러나 아무런 조건도 걸어놓지 않은 useEffect는 첫 렌더링시 "I run only once" 한번드고 더 이상 뜨지 않는 모습을 볼 수 있다.
공식 ECMA International 홈페이지에 가보면 2011 ~ 2021까지 ECMA-262 edition들을 확인 할 수 있다.
대표적인 차이점
화살표 함수
this
변수선언
모듈
클래스
템플릿 리터럴
ES6부터 새롭게 등장한 템플릿 리터럴. 덕분에 문자열 표현이 훨씬 간단해졌다. 템플릿 리터럴이란 작은 따옴표나 큰 따옴표 대신 백틱(`)으로 문자열을 감싸 표현하는 기능을 말한다. 템플릿 리터럴을 사용하면 플레이스 홀더(${variable})를 사용하여 백틱 내부에 문자열과 함께 표현식을 넣을 수 있다.
화살표 함수
ES6부터 새롭게 등장한 화살표 함수로 함수 선언법이 좀 더 간단해졌다.
변수 선언
ES5
ES5에선var밖에 존재하지 않았다.var는 변수를 선언할 때 사용되는 키워드로, 재할당과 재선언에 굉장히 자유롭다.
ES6
ES6부터let,const가 추가되었다.
let은 한번 선언된 변수에 동일한 이름으로 선언할 수 없다. 하지만, 값은 재할당 할 수 있다.
모듈
ES5 이전에는 각 기능별로 JS 파일을 나누고 개발 및 관리하는 것이 불가능했다.
ES5
ES5 에선require를 통해 모듈화를 할 수 있었다.
ES6
ES6 부터는import/export로 모듈을 관리할 수 있다. 모듈은 실현가능한 특정 프로그램의 그룹니다. 그리고 이것은 다른 파일의 변수, 함수를 참조한다. 클래스와 같은 모듈이 로딩될 때,import와export를 이용해 사용될 수 있다.
클래스
ES5
ES5에선class라는 키워드는 없었지만 프로토타입을 통해 실현 가능했다.
ES6
ES6에서는 class 키워드를 사용해서 선언할 수 있다.
2. 좋았던 점
생각보다 빠르게 Todolist를 만든것,
리액트가 꽤 재밌다는 점?
3. 개선할점 / 아쉬운점.
자바스크립트의 문법적인 것들을 정확히 모르기 때문에, 참고자료들을 봐도 정확히 이해할 수 없는 부분이 많았다. 이러한 혼공스와 모던자바스크립트 자료를 많이 봐야할 것 같다.
예를들어 Todolist를 만들면서 느낀것은 이제부터 더 많이 객체와 배열을 다룰것 같은데 객체에 대한 이론적인 정보가 부족하다고 느꼇다.
아직 react의 동작원리? 그런것에 대한 이해가 부족한 것 같다. 강의나 자료를 많이 참고해야 할듯