[TIL] 주특기 회고의 날

봄봄·2021년 10월 9일
0

항해99 회고록

목록 보기
4/8


2주간의 React 주특기 시간이 지나갔다.
React에 대해 알았는가? 라고 묻는다면 대답은 아니오다.
2주간의 시간을 그냥 버린 것 같아서 너무 아쉽다.
차라리 처음부터 과제에 매달리지 말고 개인공부의 시간을 가질걸 뒤늦게 후회를 많이 했다.
a , b를 알아야 c, d를 깨우치는 나인데
c, d부터 집어넣으니 이해가 되지 않아 너무 힘들었달까
그래도 이제라도 깨우치고 다시 기초부터 시작하는중
이제서야 아 그때 이런 문법을 썼던게 이 이유였구나 하나씩 깨달아가는중이다.
남들보다 한참 뒤쳐진 속도로 따라가는 중이라 마음이 많이 조급한데 그래도 나만의 속도로 꾸준히 가는게 중요하다고 생각한다.
하기싫은 맘 좀만 뭍어두고 열심히 해보자!! 화이팅


## 오늘의 배움

1. then과 async-awite 차이점은 무엇일까요?

async-awite는 Node.js의 또 다른 핵심요소인 제너레이터에서 파생된 형식이다.

console.log("1");
const promise = new Promise(function (resolv, reject) {
  setTimeout(function () {
    resolv("success");
  }, 1000);
});
console.log("2");
promise.then(function (value) {
  console.log(value);
});

console.log("3");

위 코드는 then을 사용한 예시이다.

해당 코드를 돌려보면 1 -> 2 -> 3 -> success의 순서로 콘솔이 찍힌다.
Promise 객체를 가지고 있는 promise라는 함수가 존재하고, 얘는 내부로직이 끝났을 때 resolve를 던진다. 예시의 내부로직은 setTimeout이기 때문에 1초가 지난 후에 resolve가 실행되는 것이다.

resolv가 던진 success라는 value는 resolv에 담겨있다.
promise가 끝나고 나서야 then이 실행되는데, promise가 성공적으로 실행된다는 전제하에 resolve에 있는value를 then으로 던진다.
value를 받은 then은 value를 사용하여 자신의 로직을 처리하게 된다.

import { async } from "@firebase/util";

console.log("1");
const promise = new Promise(function (resolv, reject) {
  setTimeout(function () {
    resolv("success");
  }, 1000);
});
console.log("2");
async function thenFunction() {
  console.log("thenFunction 함수 진입");
  const result = await promise;
  console.log(result);
}

console.log("3");

thenFunction();

console.log("4");

위 예시를 async-awite 구문을 이용하여 동일하게 처리 했다.

1 -> 2 -> 3-> thenFunction 함수 진입 -> 4 -> result 순서로 찍힌다.
3이 찍히는 시점 다음에 thenFunction을 콜하므로, thenFunction로직을 타지만 promise 함수는 비동기 처리가 되어 있어 완료할 때까지 멈춘다.
따라서 4가 먼저 찍히고 완료 후 success가 찍힌다.

차이점

  • then 로직 대신 awite를 걸고 result라는 변수를 만들어 담는다는 점이 다르다.
  • then을 이용하는 처리방식과 비교 해보면, thenFunction이 불리는 위치에 따라 동기화가 필요한 부분은 외부 함수와도 동기화를 할 수 있다는 장점이 있다.

2. 리덕스에서 지켜야할 3가지 규칙들은 무엇일까요?

  1. 하나의 애플리케이션 안에는 하나의 스토어가 있어야 한다.

    여러 개의 스토어를 사용하는 것은 가능하기는 하지만 권장되지는 않는다. 특정 업데이트가 너무 빈번하게 일어나거나, 애플리케이션의 특정 부분을 완전히 분리시키게 될 때 여러 개의 스토어를 만들 수도 있다. 하지만 이 경우, 개발 도구를 활용하지 못하게 된다.

  1. state는 읽기 전용이다.

    리액트에서 state를 업데이트 해야 할 때, setState를 사용하고, 배열을 업데이트 해야할 때는 배열 자체에 push를 직접 하지 않고, concat 같은 함수를 사용하여 기존의 배열은 수정하지 않고 새로운 배열을 만들어서 교체하는 방식으로 업데이트를 한다.

    리덕스에서도 마찬가지로 기존의 상태는 건드리지 않고 새로운 상태를 생성하여 업데이트를 한다면 나중에 개발자 도구를 통해서 뒤로 돌릴 수도 있고 다시 앞으로 돌릴 수도 있다.

    불변성을 유지하면서 상태를 관리하는데 용이하기 위해 Immer 를 사용할 수 있다.

  1. 변화를 일으키는 함수, 리듀서는 순수한 함수여야 한다.

    순수한 함수는 다음의 특징을 가지로 있다:

    • 리듀서 함수는 이전 상태와, 액션 객체를 파라미터로 받는다.
    • 이전의 상태는 절대로 건드리지 않고, 변화를 일으킨 새로운 상태 객체를 만들어서 반환한다.
    • 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과값을 반환해야만 한다.

    new Date()를 사용한다던지, 랜덤 숫자를 생성한다던지, 혹은 네트워크에 요청과 같은 작업은 실행할 때마다 다른 결과값이 나타나지 않는 순수하지 않은 작업들이다. 이 경우, 리덕스 미들웨어를 사용하여 리듀서 함수의 바깥에서 처리하면 된다.

3. s3 버킷에 배포한 뒤, 어떤도메인.com이 아닌 어떤도메인.com/login 등 페이지로 이동하면 왜 오류가 날까요?

다음은 일반적인 S3의 URL 형태입니다.

다음은 정적 웹사이트 호스팅을 사용한 S3의 URL 형태입니다.

이처럼 URL 형태에 큰 차이점이 있습니다. 아래 URL 형태처럼 버킷 이름이 서브 도메인 형태로 들어가야 DNS 서버에서 CNAME 설정을 해 줄 수 있습니다. 즉 example.com 도메인의 CNAME을 examplebucket10.s3-website-ap-northeast-1.amazonaws.com로 설정하면 example.com으로 접속했을 때 버킷(examplebucket10)의 내용이 바로 표시됩니다.

이 CNAME 설정은 AWS의 DNS 서비스인 Route 53에서 설정 가능합니다. 또한, Route 53가 아니더라도 BIND와 같은 일반적인 DNS 서버에서도 설정이 가능합니다.

리액트에서 각 페이지 컨텐츠에 맞는 미리보기(사이트 이미지, 사이트 설명 등)를 띄워주려면 어떻게 해야할까요?

react-helmet 라이브러리를 사용하며, 렌더 함수에서 Helmet 컴포넌트를 사용하여 헤더값을 설정할 수 있다.

<Helmet>
    <titie>
    <meta property = 'og:title' content = ' title ' />
    <meta property = 'og:discription' content = ' discription ' />
    <meta property = 'og:image' content = ' img url ' />
</Helmet>

4. 리덕스에서 미들웨어 청크의 역할은 뭘까요?

redux-thunk 는 redux로 동작하는 어플리케이션에서 비동기 작업을 처리할 때 사용하는 미들웨어이다. redux-thunk 를 사용하면 액션 객체가 아닌 함수dispatch 할 수 있다.

기본적으로 redux는 액션 생성자를 통해 단순한 key와value로 이루어진 액션 객체를 dispatch 한다. 이 경우, 액션 생성자는 특정 액션이 몇 초 뒤에 실행되게 하거나, 현재 상태에 따라 아예 액션이 무시될 수 있도록 할 수 없다.

// 일반적인 액션 생성자
// key-value로 이루어진 단순한 액션 객체를 생성

const actionCreator = (payload) => ({action: 'ACTION', payload});

하지만 redux-thunk를 이용하면 액션 생성자는 함수를 생성할 수 있으므로, 액션 객체가 리듀서에서 처리되기 전에 해당 함수 내에서 다양한 작업을 할 수 있다. 예를 들어, 비동기적으로 서버와 통신을 하기 위한 asyncawait뿐 아니라 현재 상태를 알기 위한 getState, 여러 액션들을 실행시킬 dispatch를 필요에 따라 사용할 수 있다.

// redux-thunk를 이용해 1초 뒤 액션을 dispatch하는 함수를 생성할 수 있음

const INCREMENT_COUNTER = 'INCREMENT_COUNTER';

function increment() {
  return {
    type: INCREMENT_COUNTER
  };
}

function incrementAsync() {
  return dispatch => { // dispatch 를 파라미터로 가지는 함수를 리턴합니다.
    setTimeout(() => {
      // 1 초뒤 dispatch 합니다
      dispatch(increment());
    }, 1000);
  };
}

5. 프로미스는 정확히 말하면 비동기가 아닙니다. 비동기와 프로미스는 각각 무엇일까요?

비동기 처리란, 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 자바스크립트의 특성을 의미한다.

자바스크립트에서는 비동기 프로그래밍의 한 가지 방식으로 callback 패턴을 많이 사용했다. callback패턴은 비동기 작업이 길어질수록 callback이 깊어지고 , 또한 에러 핸들링 및 디버깅이 어렵다.

그런 callback의 문제점을 해결하기 위해 Promise 패턴이 등장했다.비동기 작업을 callback이 아닌 then으로 연결하고 , catch 로 에러 핸들링 및 디버깅을 편하게 할 수 있다.

각 promise는 비동기 연산이 아직 완료되지 않았음을 가리키는 보류(pending) 상태에서 시작하여 짧은 생명 주기를 통과한다. 보류 promise는 미 확정(un-settled) 상태로 간주된다.

비동기 연상이 완료되면 이 promise는 확정(settled) 상태로 간주 되고 두 가지 가능한 상태 중 하나가 된다.

  1. 대기 중(pending) : 결과를 기다리고 있는 상태
  2. 이행됨(fulfilled) : 수행이 정상적으로 끝났고 결과 값을 갖고있는 상태
  3. 거부됨(rejected) : 수행이 비정상적으로 끝난 상태

즉, 비동기 적으로 작업이 실행되는데, 작업이 종료 된 후에 실행이 잘 성공했는지 , 혹은 실패했는지 , 성공과 실패 결과 값이 무엇인지 반환을 해주는 객체이다.

6. TDZ(Temporal Dead Zone/일시적 사각지대)란?

TDZ(Temporal Dead Zone일시적인 사각지대)는 스코프(변수에 접근할 수 있는 범위)의 시작 지점부터 초기화 시작 지점까지의 구간을 TDZ(Temporal Dead Zone) 라고 한다.

자바스크립트가 동작하기 전 코드를 한번 훑는데(=실행context) 그 때 var로 선언된 코드를 전부 최상위로 끌어올린다(=호이스팅). 그래서 var는 선언을 호출 아래에 해도 동작한다.

그러나 let과 const는 var와 달리 변수가 선언되기 전에 호출을 하면 ReferenceError 가 난다.

왜 에러가 날까? 호이스팅이 안 된 걸까?

정답은 호이스팅은 된다!

다만, 선언한 후, 초기화 단계에서 메모리에 공간을 확보하는데, 선언을 호이스팅해도 초기화 전까지 메모리에 공간이 확보되지 않아 변수를 참조할 수 없기 때문에 에러가 나는 것이다. (var의 경우 선언과 동시에 초기화 됨)

이것을 TDZ라고 한다.

즉, 스코프에 진입할 때 변수를 만들고, TDZ가 생성되지만 코드 실행이(=실행 컨텍스트가) 변수가 있는 실제 위치에 도달할 때까지 엑세스를 못하기 때문이다.

0개의 댓글