본문 바로가기

Sparta x 이노베이션 캠프/React

TIL)React 키워드

반응형

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

 

미들웨어는 액션이 디스패치 된 다음 리듀서에서 액션을 처리하기 전에 액션을 받아와서 액션을 취소시키거나 다른 종류의 액션을 추가적으로 디스패치하는 등 업데이트 이전에 추가적인 작업을 할 수 있도록 도와주는 역할이다. 즉 리듀서 내 로직이 실행되는 사이의 중간다리 역할을 해줄 함수들을 작성하는 공간이다.

thunk의 역할 

1) thunk를 사용하면 우리가 dispatch를 할때 객체가 아닌 함수를 dispatch 할 수 있게 해준다. 즉 dispatch(객체)가 아니라 dispatch(함수)를 할 수 있게 되는 것.

2) 그래서 중간에 우리가 하고자 하는 작업을 함수를 통해 넣을 수 있고, 그것이 중간에 실행이 되는 것이다. 그래서 아래 흐름과 같이 실행이 되며 이 함수를 thunk라 부른다.

3) 보통 우리가 리덕스 미들웨어를 사용하는 이유는 서버와의 통신을 위해 사용하는 것이 대부분.

여러분의 생각을 적어주세요

 

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

 

비동기는 함수들이 순차적으로 진행되는것이 아닌, 요청과 결과가 동시에 일어나지 않을거라는 약속이다.

자바스크립트에서 비동기 프로그래밍을 위해 콜백을 사용한다.

Promise는 전통적인 콜백 패턴이 가진 단점을 일부 보완하며 동기 처리 시점을 명확하게 표현한다.

Promise는 비동기 처리 로직을 추상화한 객체와 그것을 조작하는 방식을 말한다.

Promise 객체에서 제공하는 메서드만 사용해야 하므로 인자가 같은 방식으로 통일된다. 복잡한 비동기 처리를 쉽게 패턴화할 수 있다.

 

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

TDZ란 Temporal Dead Zone의 약자로 우리 말로 번역하면 일시적 사각지대라는 의미이며, 스코프 시작 ~ 초기화 시작 사이의 구간을 의미한다. 다른 말로 변수가 선언되고 변수의 초기화가 이루어지기 전까지의 구간이라고 말할수 있다. 그림으로 표현하면 다음과 같이 표현 할 수 있을 것 같다. 

 

TDZ 를 이해하기 위해서는 Javascript 의 변수 생성 단계를 먼저 알아야 합니다.

1. 선언 단계 (Declaration phase)

변수를 실행 컨텍스트의 변수 객체에 등록하는 단계

2. 초기화 단계 (Initialization phase)

실행 컨텍스트에 등록한 변수를 위한 메모리를 만드는 단계, 메모리가 만들어지면 처음에는 undefined 가 할당

3. 할당 단계 (Assignment phase)

사용자가 undefined 로 할당된 변수에 다른 값을 할당하는 단계

* var 는 선언과 초기화 단계가 동시에 이루어집니다.

* let, const 는 선언, 초기화, 할당 단계가 각각 따로 이루어집니다.

* function (함수 선언문) 은 선언, 초기화, 할당 단계가 동시에 이루어집니다.

그렇기 때문에 선언과 초기화 단계가 따로 이루어 지는 let, const 같은 경우는 TDZ에 영향을 받을 수 밖에 없습니다.

 TDZ 에 영향을 받는 것

TDZ 에 영향을 받는 것으로는 다음과 같이 나열 할 수 있을 것 같습니다.

1. let

2. const

3. class 

4. class의 constructor() 내부의 super() (해당 클래스의 contructor 에서 super 함수가 호출되기 전까지는 해당 클래스에서 this 를 참조하면 에러 발생)

5. 함수 매개변수 (매개변수 선언 전에 참조하면 에러 발생)

 TDZ 에 영향을 받지 않는 것

TDZ 에 영향을 받지 않는 것으로는 다음과 같이 나열 할 수 있을 것 같습니다.

1. var

2. function (함수 선언식)

3. import (import 구문) 

var 키워드의 라이프사이클

console.log(a) //undefined

var a = "hi"

console.log(a) //hi

var로 선언한 변수는 변수 선언전에 선언 단계와 초기화 단계를 동시에 진행한다.
그래서 javascript는 실행 컨텍스트 변수 객체의 변수를 등록하고 메모리를 undefined로 만든다.
그렇기 때문에 변수 선언 전에 호출을 해도 undefined로 호출이 되는 호이스팅이 발생한다.

let 키워드의 라이프사이클

console.log(b) //Reference Error: b is not defined

let b = "hi"

console.log(b)

let으로 선언한 변수를 이전에 사용하려고 하면 Reference Error가 발생한다. 이를 보면 호이스팅이 발생하지 않는다고 보일 수 있다.

하지만, 호이스팅이 일어나 메모리 공간을 확보한 뒤, 일시적 사각지대(TDZ) 에 빠져있는 상태이기 때문에 Reference Error가 발생하는 것이다.

DIY Section

 🔑 Q1. JavaScript findIndex함수를 이용해 특정 배열의 요소 찾아내기

const editedIndex = array.findIndex(item => item.id === id)
const editedArray = [...array.slice(0, editedIndex),
                          data,
                    ...Array.slice(editedIndex +1),]

slice함수는 배열로 부터 특정 범위를 복사한 값들을 담고 있는 새로운 배열을 만드는데 사용합니다. 첫번째 인자로 시작 인덱스(index), 두번째 인자로 종료 인덱스를 받으며, 시작 인덱스부터 종료 인덱스까지 값을 복사하여 반환합니다.

 

예시 ) editedIndex는 array에 findIndex함수를 적용해서 item의 id와 내가 찾고자 하는 item의 id를 비교해 index를 찾아주고

editedArray는 array를 복사한 값을 slice 함수로 0부터 editedIndex 전까지 한 배열을 만들어주고, data에 해당하는 값을 하나의 array로, editedIndex+1 부터 array 배열의 끝까지 한 배열을 만들어 줌. 이것을 이용해서 data를 뺄수도 원하는 data를 수정할 수도 있다.

 

 🔑 Q2. Splice함수

이 함수는 배열로부터 특정 범위를 삭제하거나 새로운 값을 추가 또는 기존 값을 대체할 수 있다. 첫번째 인자로 시작 인덱스, 두번째 인자로 몇개의 값을 삭제할지, 그리고 세번째 인자부터는 추가할 값을 가변 인자로 넘길 수 있으며, 삭제된 값을 담고 있는 배열을 반환한다.

> nums = Array(20).fill().map((_, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

이 숫자 배열에서 인덱스 5가 가리키는 값부터 3개 값 삭제

> nums.splice(5, 3)
< [5, 6, 7]
> nums
< [0, 1, 2, 3, 4, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

삭제된 3개의 값을 담고 있는 배열이 반환되며, 원본 배열로 부터 3개의 값이 빠져나갔음.

 

다음은 인덱스 5가 가리키는 값부터 아무 값도 삭제하지 않고, -5, -6, -7 추가

> nums.splice(5, 0, -5, -6, -7)
< []
> nums
< [0, 1, 2, 3, 4, -5, -6, -7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

삭제된 값이 없으므로 빈 배열이 반환되고, 이전에 삭제된 값이 삭제된 자리에 -5, -6, -7이 들어갔음.

 

이번엔 인덱스 10이 가리키는 값부터 2개의 값을 -10, -11로 대체

> nums.splice(10, 2, -10, -11)
< [10, 11]
> nums
< [0, 1, 2, 3, 4, -5, -6, -7, 8, 9, -10, -11, 12, 13, 14, 15, 16, 17, 18, 19]

삭제된 2개의 값을 담고있는 배열이 반환되고, 원본 배열의 10, 11이 있던 자리에 -10, -11이 들어가있음.

splice() 함수에 첫번째 인자만 넘기면 해당 인덱스가 가리키는 값을 포함해서 배열의 마지막 값까지 삭제가 된다.

> nums.splice(15)
< [15, 16, 17, 18, 19]
> nums
< [0, 1, 2, 3, 4, -5, -6, -7, 8, 9, -10, -11, 12, 13, 14]

여기서 가장 주의할 부분은 삭제된 값을 담고 있는 새로운 배열이 반환될 뿐 아니라 원본 배열에도 변경이 가해진다. 따라서 의도치 않은 데이터 유실이나 변경으로 이어질 수 있어 데이터의 불변성이 보장되어야 하는 프로그램을 작성할 때 주의해야 한다.

 

🔑Q3. slice() vs splice()

많은 자바스크립트 개발자들이 slice()와 splice() 를 헷갈려하는 이유는 비단 이름이 비슷해서 뿐만 아니라 실제로 동일한 목적을 위해 두 함수 중 아무것이나 사용해도 무방한 경우가 있어서이다. 

예를 들어, nums 배열에서 5부터 7까지를 복사한 값을 담고 있는 새로운 배열을 얻고 싶을 때 다음 두가지 방법을 다 쓸 수 있다.

> nums = Array(20).fill().map((_, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
> nums.slice(5, 8)
< [5, 6, 7]
> nums.splice(5, 3)
< [5, 6, 7]

차이점이라면 두번째 인자로 slice()는 종료 인덱스, splice()는 몇개의 값을 떼어낼지 넘긴다는 것 뿐이다.

하지만 이 두 함수를 동일한 배열을 대상으로 여러 번 호출할 수 있는 상황이라면 얘기가 좀 틀려진다.

> nums = Array(20).fill().map((_, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
> nums.slice(5, 8) // slice() 1회 호출
< [5, 6, 7]
> nums.slice(5, 8) // slice() 2회 호출
< [5, 6, 7]
> nums.slice(5, 8) // slice() 3회 호출
< [5, 6, 7]
> nums.slice(5, 3) // splice() 1회 호출
< [5, 6, 7]
> nums.splice(5, 3) // splice() 2회 호출
< [8, 9, 10]
> nums.splice(5, 3) // splice() 3회 호출

항상 같은 배열을 반환하는 slice()와 달리 splice()는 계속해서 원본 배열을 깎아먹기 때문에 동일한 인자로 여러번 함수를 호출하게 되면 매번 다른 배열이 반환되게 된다.

 

 🔑 Q4. 매개변수 (parameter)와 인자(argument)란?

function testFun(a,b) {
    return a + b
} 

testFun(2,3);

위 코드에서 함수를 선언할 때 (a, b)의 a, b가 매개변수 (parameter)이며 매개변수는 말 그대로 변수이다. 또한 함수를 호출할 때의 (2,3)이 변수에 들어가는 값이며 인자 (arguments)라고 한다.

 

인자

인자의 특징

자바스크립트에서는 함수를 호출할 때 arguments 객체가 함수 내부로 전달된다.

arguments 객체는 함수를 호출할 때 넘긴 인자들이 배열 형태로 저장된 객체를 말한다.

function testFun(arg1, arg2) {
    console.log(arg1, arg2);
};

testFun(); // undefined undefined ------(1)
testFun(1); // 1 undefined -------------(1)
testFun(1, 2); // 1 2
testFun(1, 2, 3); // 1 2 3 -------------(2)

위의 코드에서 유추할 수 있는 arguments의 특징은 아래와 같다.

1. 함수의 매개변수보다 적게 인자를 전달 할 경우와 전달되지 않은 인자에는 undefined값이 할당된다.

2. 매개변수보다 많게 인자를 전달 할 경우 초과된 인수는 무시되지만 arguments라는 객체에 할당된다.

(+) arguments는 지역변수이며, arguments 객체를 통해 초과로 전달된 인자를 참조 할 수 있다.

매개변수 개수가 정확하게 정해지지 않은 함수를 구현하거나 전달된 인자의 개수에 따라 서로 다른 처리를 해주어야 하는 함수를 생성할 때 유용하다. 

인자의 구조

arguments 객체는 3부분으로 구성되어 있으며 아래와 같은 특징 때문에 유사 배열이라고 불린다.

  • 함수를 호출할 때 넘겨진 인자 (index 배열 형태)

->arguments[index]를 통해 함수에 들어온 인자의 특정 자릿수의 값을 알 수 있다.

  • length 프로퍼티

->arguments.length를 통해 이 객체 안에 몇 개의 인자를 가졌는지 알 수 있다.

->배열과 유사하게 동작하지만 유사 배열 객체이므로 배열 메서드를 사용할 수는 없다.

  • callee 프로퍼티

실행 중인 함수의 참조값

 

 🔑 Q5. Axios 인스턴스, 인터셉터란?

인스턴스 만들기

사용자 지정 config로 새로운 Axios 인스턴스를 만들수 있다.

axios.create([config])

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

인스턴스 메소드

다음은 사용 가능한 인스턴스 메소드입니다. 지정된 config가 인스턴스 config와 결합됩니다.

axios#request(config)

axios#get(url[, config])

axios#delete(url[, config])

axios#head(url[, config])

axios#options(url[, config])

axios#post(url[, data[, config]])

axios#put(url[, data[, config]])

axios#patch(url[, data[, config]])

axios#getUri([config])

 

인터셉터

then 또는 catch로 처리되기 전에 요청과 응답을 가로챌수 있다.

// 요청 인터셉터 추가하기
axios.interceptors.request.use(function (config) {
    // 요청이 전달되기 전에 작업 수행
    return config;
  }, function (error) {
    // 요청 오류가 있는 작업 수행
    return Promise.reject(error);
  });

// 응답 인터셉터 추가하기
axios.interceptors.response.use(function (response) {
    // 2xx 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
    // 응답 데이터가 있는 작업 수행
    return response;
  }, function (error) {
    // 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
    // 응답 오류가 있는 작업 수행
    return Promise.reject(error);
  });

나중에 필요할때 인터셉터를 제거할 수 있다.

const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

커스텀 인스턴스에서도 인터셉터를 추가할 수 있다.

const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

 

더 알아보기

Fetch API vs Axios

Fetch API 는 Web API이기 때문에 지원되는 브라우저에서는 별도의 설치과정 없이 바로 사용이 가능하다.

Fetch API를 지원하는 브라우저는 아래와 같으며 IE를 제외한 대부분 모던 브라우저에서 지원하고 있다.

출처 :&nbsp; https://caniuse.com

 

fetch의 기본적인 사용법

// GET 방식
fetch(URL, OPTIONS?)
.then(response => response.json())
.then(data => console.log(data))

// POST방식
fetch(URL, {
 method: "POST",
 OPTIONS?
})
.then(response => response.json())
.then(data => console.log(data))

fetch는 메소드 형태로 사용하며 첫번째 인자에는 요청 할 대상의 URL, 두번째 인자에는 요청에 대한 옵션을 객체형태로 넣을 수 있다.

fetch는 method를 생략하면 GET요청으로 간주되기 때문에 만약 POST방식으로 요청을 보내고자 할 경우 {method: "POST"} 옵션을 꼭 명시해주어야 한다. 

 

두번째 인자에 들어가는 요청에 대한 옵션 중 자주 사용되는 옵션들은 아래와 같다.

key             value
method GET, POST와 같은 HTTP method를 명시하는 옵션입니다. 명시하지 않을 경우 GET으로 처리됩니다.
headers 요청 헤더에 포함될 내용이 들어가는곳입니다.
보통 보내는 데이터의 컨텐츠 타입을 명시하기 위해 Content-Type을 요청 헤더에 추가할 때 사용됩니다.
body POST메소드와 같이 데이터를 보내는 요청을 할 때 데이터를 이 body의 값으로 넣으면 됩니다.
(String, FormData, Blob-파일, ArrayBuffer등의 형태로 전송할 수 있습니다.)
mode CORS와 관련된 설정입니다. (Ex. cors, no-cors, same-origin 등)
credentials 요청에 쿠키를 포함하고 싶거나 사용자에 대한 인증이 필요할 때 사용하는 옵션입니다.
fetch는 기본적으로 credentials에 별도의 설정을 하지 않으면 쿠키를 포함할 수 없습니다.

위의 예제는&nbsp; jsonplaceholder 를 이용해서 GET 방식으로 데이터를 요청해 본 코드입니다.

요청 후 응답이 왔을 때는 위 사진처럼 promise객체 형태로 반환되는 최초 응답 값을 볼 수 있고 이 객체 내부에는 요청과 응답에 관련된 속성들이 포함되어있다. Fetch API의 응답에서는 데이터에 바로 접근할 수 없고 json메소드를 통해 promise객체 내부에 있는 데이터를 변환하는 과정이 필요하다.

응답 객체 내부의 status와 ok의 속성 값을 통해 응답이 정상적으로 도착했는지 판단할 수 있으며 ok는 boolean타입으로 200번대의 HTTP 상태코드이면 true, 그 외에는 false값을 가진다.
status의 값은 HTTP 상태코드를 뜻하며 200번대라면 응답 데이터가 도착한것.

위 사진의 경우 json메소드를 통해 응답 데이터를 json으로 변환된 결과를 보여주고 있으며 변환이 완료된 위의 상태부터 응답 데이터를 사용할 수 있다. POST방식에서는 fetch메소드의 두번째 인자인 options내부에 객체형태로 보내고자 하는 데이터를
body에 넣어주고 요청헤더에 Content-type을 명시해서 보내야 합니다. 또한 꼭 HTTP 메소드를 POST로 지정해주어야 한다.

POST방식으로 요청을 보낼 경우 HTTP의 상태 코드는 201로 오는 경우가 많으며 201은 요청이 정상적으로 전달되었으며 요청시에 보낸 데이터로 자원이 생성되었다는 뜻을 가지고 있다.

 

Axios

Axios는 Fetch API와는 다르게 라이브러리이기 때문에 별도의 설치과정이 필요하다.

그래서 라이브러리를 설치해야하는 불편함이 따르지만 Fetch API보다 지원이되는 브라우저의 폭이 넓고 더 다양한 기능을 가지고 있다.

Fetch API의 경우 Web API로서 브라우저에서만 사용이 가능하지만 axios는 서버사이드 환경도 지원하기 때문에 브라우저와 노드환경 모두 사용이 가능하다. 브라우저에서 동작할 때는 XHR객체를 사용하고 서버사이드 환경에는 http api를 사용한다.

사용법

메소드 형식과 객체 형식 두가지 문법으로 사용이 가능하다.

// 메소드 형식
axios.get('https://jsonplaceholder.typicode.com/todos/1')
.then(res => console.log(res));

// 객체 형식
axios({
 method: 'get',
 url: 'https://jsonplaceholder.typicode.com/todos/1',
})
.then(res => console.log(res))

Axios의 응답은 아래와 같으며 요청과 관련된 정보(요청 설정값, 요청헤더), 응답 데이터, status등이 포함되어있다.

Fetch와는 다르게 응답을 받으면서 데이터를 json으로 변환시켜주는 과정이 포함되어있어서 별도의 변환과정없이 응답후 객체 내부의 data속성을 통해 응답 데이터에 바로 접근 가능.

Axios는 get 뿐 아니라 post, put, delete, patch 등 HTTP method 종류에 따라 사용가능하도록 다양한 메소드를 지원하고 config를 통해 요청에 관련된 설정 할 수 있다.

 

Axios

장점

  • response timeout 처리 방법이 있다. (fetch에는 존재하지 않는 기능)
  • promise 기반으로 다루기가 쉽다
  • 크로스 브라우징에 신경을 많이썼기에 브라우저 호환성이 뛰어나다.

단점

  • 모듈 설치를 해줘야한다.

fetch

장점

  • 내장 라이브러리이기에 별도의 import를 해줄 필요가 없다.
  • promise 기반으로 다루기가 쉽다.
  • 내장 라이브러리이기에 사용하는 프레임워크가 안정적이지 않을 때 사용하기 좋다.

단점

  • internet explorer의 경우에는 fetch를 지원하지 않는 버전도 존재한다. (브라우저 호환성이 상대적으로 떨어진다.)
  • 기능이 부족하다.

 

 

 

 

 

 

https://react.vlpt.us/redux-middleware/

 

7장. 리덕스 미들웨어 · GitBook

리덕스 미들웨어 리덕스 미들웨어는 리덕스가 지니고 있는 핵심 기능입니다. Context API 또는 MobX를 사용하는것과 차별화가 되는 부분이죠. 리덕스 미들웨어를 사용하면 액션이 디스패치 된 다음,

react.vlpt.us

https://kimnamsun.github.io/blog/2021-08-30/

 

TDZ (Temporal Dead Zone)

FrontEnd Developer KIMNAMSUN

kimnamsun.github.io

https://www.daleseo.com/js-array-slice-splice/

 

자바스크립트 배열의 slice()와 splice() 함수

Engineering Blog by Dale Seo

www.daleseo.com

https://axios-http.com/kr/docs/interceptors

 

인터셉터 | Axios Docs

인터셉터 then 또는 catch로 처리되기 전에 요청과 응답을 가로챌수 있습니다. axios.interceptors.request.use(function (config) { return config; }, function (error) { return Promise.reject(error); }); axios.interceptors.response.use(f

axios-http.com

https://velog.io/@sisofiy626/JavaScript-Fetch-API%EC%99%80-Axios

 

[JavaScript] Fetch API vs Axios

Fetch API vs Axios 오늘 다룰 주제는 Fetch API와 Axios 입니다. 지난 AJAX와 XHR편에서 AJAX의 기술 중 비동기 통신을 위해 사용되는 XHR객체를 알아봤었는데

velog.io

javascript info

 

fetch

 

ko.javascript.info

kysung95 | Velog

 

[개발상식] Ajax와 Axios 그리고 fetch

여러분들이 프로젝트를 진행하다보면 클라이언트와 서버 간 데이터를 주고받기 위해 HTTP 통신을 사용하게될겁니다. 주로 어떤것을 사용하시나요? 또, 그것에 대해 얼마나 알고계시나요? 저와

velog.io

 

반응형

'Sparta x 이노베이션 캠프 > React' 카테고리의 다른 글

WIL: Axios  (0) 2022.09.04
TIL : API란 무엇인가요?  (0) 2022.09.02
TIL) async & await  (0) 2022.08.26
TIL) Promise  (0) 2022.08.26
TIL) useEffect  (0) 2022.08.24