-
useEffect
렌더링할 때 side effect를 발생시키기 위해 사용하는 리액트 훅이다.
useEffect(() => { // effect return () => {//cleanup}; }, dependencies);
와 같이 사용하고,
dependencies로 effect를 발생시킬 시점을 조절할 수 있다.
useEffect(() => { });
위와 같이 사용하면 렌더링이 될 때마다 useEffect 내부가 실행되고,useEffect(() => { }, []);
위와 같이 사용하면 컴포넌트가 나타났을 때 한 번 useEffect 내부가 실행되고,useEffect(() => { }, [value1, value2 ..]);
위와 같이 사용하면 컴포넌트가 나타났을 때, 그리고 value1, value2등 dependencies에 포함된 값이 기존 렌더링 값과 달라졌을 때 (Object.is()기준으로) useEffect 내부가 실행된다.이 때 주의할 점은 Object.is() 기준이기 때문에 함수, object등을 dependencies에 넣을 때 주의해야 한다.렌더링될 때마다 객체는 새로운 reference를 갖게 되어 useEffect내부를 의도치 않게 매 렌더링 시에 실행하게될 수 있기 때문이다.Axios
브라우저와 node.js를 위한 Promise기반 HTTP 클라이언트이다.
axios를 이용하면 브라우저에서 XMLHttpRequests를 할 수 있고,
요청과 응답을 가로채거나 변경할 수 있고,
요청을 취소할 수도 있다.
axios.get(url[,config])처럼
axios.<method>() 방식으로 사용할 수 있고,
만약 instance를 만들고 싶다면 axios.create([config])를 이용하면 된다.
Promise기반이므로 async, await을 이용해서 조금 더 편하게 사용할 수 있다.
Promise
const promise = new Promise(function(resolve, reject) { // });
위와 같이 프로미스 객체를 생성할 수 있다.
어떤 시간이 오래걸리는 일을 수행할 때 사용하게 된다.
new Promise안에 인자로 들어가는 함수를 executor라고 하고, executor는 new Promise가 생성될 때 자동으로 실행된다.
이 executor가 보통 시간이 오래 걸리는 일을 수행한다.
executor는 resolve와 reject 함수를 인자로 받고, resolve나 reject 중 적어도 하나를 반드시 호출한다.
프로미스 객체는 pending, fulfilled, rejected 세 가지 상태를 가질 수 있다.
그리고 각각의 상태에 해당하는 result값은 각각 undefined, value, error이다.
.then, .catch, .finally로 프라미스가 처리됐을 때 실행할 함수를 지정할 수 있다.
.then은 첫 인자로 프로미스 객체가 fulfilled 상태일 때 실행할 함수를 받고,
두 번째 인자로 프로미스 객체가 reject 상태일 때 실행할 함수를 받는다.
.catch는 프로미스 객체가 reject상태일 때 실행할 함수를 인자로 받는다.
.then(null, someFunction)를 .catch(someFunction)으로 간단하게 표현할 수 있다.
그리고 프로미스 객체가 fulfilled나 reject상태일 때 언제나 실행할 함수를 .finally의 인자에 넣어서 처리할 수 있다.
그리고 .then, .catch, .finally는 프로미스 객체를 반환하기 때문에 한 프로미스에 여러 핸들러를 등록하는 프로미스 체이닝이 가능하다.
동기 / 비동기
동기적인 코드는 무조건 순차적으로 실행이된다.
즉 한 줄이 끝나야 다음 줄로 넘어가는 코드이기 때문에 앞의 코드가 매우 오래 걸리는 코드라면
그 코드가 실행될 때까지 다른 코드가 실행되지 않고 무한정 기다리게 된다.
브라우저 환경에서는 만약 오래 걸리는 코드를 실행했을 때 동기적으로 동작한다면
그 코드가 완료될 때까지 다른 어떤 것도 할 수 없는 블로킹이 발생한다.
따라서 오래 걸리는 코드는 따로 처리해서 오래 걸리는 작업을 실행해도 블로킹이 발생하지 않도록 동작하는 방식이 비동기 방식이고,
브라우저는 비동기 방식으로 동작한다.
따라서 엄청 큰 용량의 데이터를 받아오는 작업을 실행하는 동안에도 스크롤을 해서 다른 부분을 보거나 버튼들을 클릭을 할 수 있다.
Callback
콜백혹은 콜백 함수는 인자로 넘겨주는 실행 가능한 코드를 의미한다.
그리고 인자로 콜백 함수를 받은 코드는 그 콜백 함수를 실행한다.
비동기 방식에서 콜백 함수를 자주 사용한다.
비동기 코드가 실행이 완료되었을 때 어떤 함수를 실행하고 싶다면 콜백으로 넘겨서 처리하는 방법이 있다.
하지만 콜백 방식은 비동기 함수의 콜백으로 비동기 함수를 사용하여 여러번 연속으로 처리하는 경우에 콜백지옥에 빠질 수 있다.
이 때 async-await 방식을 이용하면 동기 코드와 비슷하게 작성을 할 수 있기 때문에 async-await방식을 활용하면 좋다.
async-await
async-await을 사용하면 프라미스를 편하게 사용할 수 있다.
async는 함수 선언 앞에 붙여준다.
그리고 async를 붙인 함수는 프라미스가 아닌 것을 반환하더라도 프라미스로 감싸 반환하기 때문에 항상 프라미스를 반환한다.
또한 await는 async함수에서만 동작한다.
async함수에서 await을 쓰면 해당 부분에서 프라미스가 처리될 때까지 기다리게 된다.
그리고 프라미스가 처리되면 그 다음 코드가 실행된다.
따라서 async await을 쓰면 비동기 코드를 동기 코드처럼 작성할 수 있게 된다.
React Custom Hook
커스텀 훅을 사용하면 데이터를 받아오는 등의 특정 로직을 재사용 가능한 함수로 빼낼 수 있게 된다.
여러 컴포넌트에서 공통적으로 사용하는 로직을 추출해서 커스텀 훅으로 빼내면 유용하다.
이 때 아무 로직이나 훅으로 만드는 것은 아니고,
훅을 사용하는 로직만 use~~~의 이름으로 정의하여 커스텀 훅으로 만든다.
훅을 포함하지 않은 로직은 use를 붙이지 않은 그냥 함수로 만들어야 한다.
jest.mock()
jest테스트를 할 때 어떤 것을 모킹하고 싶을 때 사용한다.
모킹을 하고 싶은 경우에는 실제로 실행을 하지 않고, 그 코드가 실제로 호출되는지만 확인하고 싶은 경우 등이 있을 수 있다.
jest.mock으로 모듈도 모킹을 할 수 있다.
모킹을 하는 경우에는 각각의 테스트의 독립성을 보장하기 위해 mock을 clear를 꼭 해주는 것이 바람직하다.
jest.fn()
어떤 모킹한 가짜 함수를 만들 때 사용한다.
jest.fn()을 대입한 값에 mockReturnValue나 mockImplementation등의 메서드를 사용해서
모킹 함수를 조금 더 구체적으로 설정해줄 수 있다.
Flux Architecture
페이스북이 클라이언트 웹 앱을 만들 때 사용하는 아키텍처로,
Dispatcher, Stores, Views(React 컴포넌트)의 세가지 핵심 파트로 구성된다.
flux architecture에서 데이터는 단 방향으로 흐른다.
액션은 type과 새로운 data를 담고 있는 객체인데, view는 새로운 액션을 생성할 수 있다.
dispatcher는 모든 데이터 흐름을 관리하고, 들어온 액션을 stores에 전달한다.
stores는 어플리케이션 상태와 로직을 포함한다.
views는 stores의 상태를 반영해서 보여준다.
Pub-Sub (Publish-subscribe pattern)
publish-subscribe pattern은 메세징 패턴이고,
메시지를 전송하는 publishers가 있고, 메시지를 받는 subscribers가 있는데,
publishers가 특정 topic에 대해 발행한 message는 topic을 구독하는 모든 subscribers에게 전달된다.
JavaScript Set
요소가 중복되지 않게 저장되는 방식의 자료구조이다.
요소가 중복인지 아닌지는 SameValueZero알고리즘으로 판단한다.
SameValueZero알고리즘은 NaN과 NaN을 동일하게 판단하고, 0, +0, -0을 동일하게 판단하고 나머지는 ===로 비교한다.
add메서드로 요소를 추가할 수 있고,
delete메서드로 요소를 삭제할 수 있다.
has메서드로 값이 포함되어 있는지 확인할 수 있다.
Redux
상태 관리를 위한 오픈 소스 자바스크립트 라이브러리이다.
Flux architecture와 유사하다.
모든 상태는 store에 포함되어 있고,
무슨일이 발생했는지 알려주는 action을 생성해서 store로 dispatch해야만 상태를 바꿀 수 있다.
이 때 리듀서가 현재 상태와 액션을 받아서 새로운 상태를 계산한다.
MobX
객체 지향적으로 코드를 작성할 수 있는 상태 관리 라이브러리이다.
stores에서 상태와 로직을 관리하는데,
특정 상태가 변할 때 리렌더링하고 싶은 경우 MobX에서는 해당 상태를 observable state로 만들고,
이벤트로 발생한 액션이 observable state를 변경하면 computed value가 변경되고, 리렌더링 등의 side effect가 발생한다.
event.stopPropagation()
event의 캡처링과 버블링을 멈춘다.
이벤트 캡처링은 특정 요소에서 발생한 이벤트를 하위 요소들에게 전달하는 특성이다.
이벤트 버블링은 특정 요소에서 발생한 이벤트가 상위 요소들에게 전달되는 특성을 의미한다.
브라우저는 특정 요소에서 이벤트가 발생하면 상위 요소들에게 전달되어 최상위에 있는 요소까지 이벤트를 전달한다.
따라서 상위 요소에 이벤트 전달을 막고 싶다면 event.stopPropagation()을 이용할 수 있다.
event.preventDefault()
event의 default 액션 실행을 막는다.
하지만 event의 propagation을 막지는 않기 때문에 propagation을 막으려면 event.stopPropagation()도 실행해야 한다.
default 액션의 예로는 링크를 클릭했을 때 URL로 이동하거나,
form의 submit버튼을 눌렀을 때 서버로 제출하는 등의 액션이 있다.
reduce
배열에 적용할 수 있는 메서드 중 하나로, 매우 강력하다!
콜백으로 reducer라는 함수를 받아서 누적된 값과 현재 요소를 바탕으로 값을 누적하여 반환한다.
reduce((accumulator, currentValue) => { /* … */ }) reduce((accumulator, currentValue, currentIndex) => { /* … */ }) reduce((accumulator, currentValue, currentIndex, array) => { /* … */ }) reduce((accumulator, currentValue) => { /* … */ }, initialValue) reduce((accumulator, currentValue, currentIndex) => { /* … */ }, initialValue) reduce((accumulator, currentValue, currentIndex, array) => { /* … */ }, initialValue)
위와 같이 다양한 방식으로 사용할 수 있다.
만약 initialValue를 넣어주지 않으면 accumulator의 초기 값은 배열의 첫 값이 되고, currentValue는 배열의 두번째 값으로 초기화된다.
만약 initialValue를 넣어주면 accumulator의 초기값이 initialValue가 되고, currentValue는 배열의 첫 값으로 초기화된다.
자바스크립트 상속
자바스크립트에서 class문법을 사용하는 경우 extends 키워드를 통해 상속을 할 수 있다.
자바스크립트는 프로토타입 기반 언어이기 때문에 extends도 프로토타입을 기반으로 동작한다.
상위 클래스의 메서드를 하위클래스에서 재정의하면 오버라이딩 되기 때문에
오버라이딩 된 메서드를 실행하면 재정의된 메서드가 사용된다.
그리고 만약 생성자를 오버라이딩 하는 경우에는 반드시 super(...)를 this를 사용하기 전에 호출해야 한다.