안녕하세요, 패스트 캠퍼스 메가바이트 스쿨 프론트 엔드 3기 수료 중인 김당퀔입니다! 이번 3기 수료 기간은 9월 13일부터 4월 14일까지 총 7개월 과정입니다. 7개월 동안 매주 주말 회고록을 작성해 보려고 합니다.
블로그 제출 기한으로 인해서 지난 금요일부터 해당 주 목요일까지의 사이클로 작성됩니다.
HTTP 기반 통신을 지원하는 가장 많이 사용되는 자바스크립트 라이브러리.
구분 | axios | fetch |
---|---|---|
모듈 설치 | npm install --save axios | 브라우저 내장 API |
Promise API | 사용 | 사용 |
timeout 기능 | 지원, tiemout 시간 내에 응답이 오지 않으면 중단시킬 수 있음 | 지원하지 않음 |
JSON 자동 변환 | 지원, Content-type 정보를 이용해 자동으로 객체로 변환 | 지원하지 않음 |
크로스 오리진 (cross origin) 문제란 브라우저는 자신의 오리진과 다른 오리진의 API 서버와 통신할 때 문제가 발생한다
는 개념. 크로스 오리진 문제를 발생시킴으로써 잠재적인 위험을 가진 문서의 로딩을 제한해 브라우저 공격의 가능성을 줄일 수 있다. 웹 브라우저에 내장된 SOP(Same Origin Policy: 동일 근원 정책)라는 보안 정책 때문에 발생.
크로스 오리진의 브라우저가 백엔드 API 서버로 요청했을 때 서버에서 Access-Control-Allow-Origin HTTP 헤더로 브라우저의 오리진을 응답하여 브라우저가 통신 및 데이터 로딩을 할 수 있도록 허용하는 방법.
프론트엔드 애플리케이션을 호스팅하는 서버에 프록시를 설치하여 프론트 서버의 프로시를 거쳐서 백엔드 API와 통신하도록 하여 브라우저 측에서는 동일한 오리진과 통신하도록 하는 방법.
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
//https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
proxy: {
"/api": {
target: "http://localhost:8000",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
});
CRA에서 프록시 설정 방법
// src/setupProxy.js
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
"/api",
createProxyMiddleware({
target: "http://localhost:8000",
changeOrigin: true,
pathRewrite: {
"^/api": "",
},
})
);
};
axios.get(url, config)
axios.post(url, data, config)
axios.put(url, config)
axios.delete(url, data, config)
axios.defaults.baseURL = '/api/todolist_long'
axios.get('/gdhond')
과 같이 사용할 수 있다.axios.defaults.headers.common['Authorization'] = JWT
axios.defaults.timeout = 2000
대규모 애플리케이션에서 일관된 데이터 관리를 손쉽게 하기 위해 만들어진 단방향 데이터 처리 과정을 가지는 아키텍처. 플럭스 아키텍처는 단일 디스패처를 이용. 모든 데이터 흐름은 단일 디스패처를 거쳐 가므로 이곳에서만 모니터링과 로깅을 하면 모든 액션의 흐름을 볼 수 있으며, 액션에 의해 상태가 어떻게 변경돼가는지를 손쉽게 추적 가능.
{type: "addTodo", payload: {todo: "공부하기", desc: "리덕스"}}
리덕스는 댄 아브라모프라는 개발자가 만든 자바스크립트 애플리케이션을 위한 예측 가능한 상태 관리 컨테이너. 플럭스의 기능과 더불어 핫 리로딩 (hot reloading), 시간 여행 디버깅(time travel debugging)과 같은 기능을 제공.
리덕스의 스토어는 상태만 가지고 상태 변경의 기능을 리듀서라는 요소로 분리. 이 결과 변경 로직이 개발 중에 변경되더라도 상태를 유지시킬 수 있다. 이 기능을 핫 리로딩이라고 한다. 리듀서를 이용해 상태를 변경할 때 기존 상태 객체를 변경하지 않고 새로운 상태 객체를 생성한다.
리덕스의 불변성을 가지는 상태 변경은 시간 흐름에 따라 상태의 이력을 남긴다. 상태 변경 이력은 시간 흐름에 따라 상태가 어떻게 변경됐는지 손쉽게 추적할 수 있게 해 준다. 그리고 애플리케이션 개발 중에 과거의 어느 한 시점의 상태로 돌아가서 다시 기능을 확인할 수 있어 디버깅에 유용하다. 이런 디버깅 기능을 시간 여행 디버깅이라고 한다.
(state, action) => {...}
리덕스 아키텍처에서 스토어는 단 하나이다. 스토어의 상태는 읽기 전용, 상태 변경은 리듀서에 의해서만 수행해야 한다. 리듀서는 여러 개 만들 수 있는데 상태 변경 로직을 포함하면서 더불어 스토어가 가지는 초기 상태를 전달해 주는 역할을 한다. 리듀서는 순수 함수여야 한다.
액션이 스토어로 전달된 후 리듀서에 도달하기 전과 상태 변경이 완료된 후에 수행할 중앙집중화된 작업을 지정할 수 있는 함수. 리덕스 미들웨어는 스토어 내부에 등록한다. 리덕스가 단일 스토어 아키텍처이기 때문에 스토어에 들여다 볼 수 있는 요소를 설치하면 모니터링, 비동기, 로깅 등의 다양한 작업을 수행할 수 있는데, 스토어에 설치하는 요소가 리덕스 미들웨어이다.
middleware(store)(next)(action)
이런 형태의 커링 함수(curring)를 사용하게 되는데 store는 리덕스 스토어, action은 스토어로 전달되는 액션 메시지, next는 dispatch() 함수이다. 한 미들웨어에서 리듀서로 전달하기 전의 실행이 완료되면 next(action)을 호출하여 다음 리듀서로 action을 전달해 줄 수 있다. 만약 액션을 전달해 주지 않으면 다음 미들웨어는 물론이고 리듀서로 액션이 전달되지 않으므로 상태를 변경하지 않을 것이다.
미들웨어를 추가하려면 순서대로 concat()함수로 추가한다.
@reduxjs/toolkit은 직렬화 가능 여부, 불변성 제공 여부를 체크하는 내장된 기본 미들웨어와 비동기 처리를 위한 redux-thunk 기능을 제공하는 미들웨어를 내장하고 있다. 해당 프로젝트의 Date 타입을 사용하는 currentTime은 직렬화가 지원되지 않으므로 경고가 발생할 수 있으므로 serializableCheck 옵션을 false로 지정하였다.
loggerMW의 내용을 개발할 때 확인할 수 있는 것
리듀서는 비동기 처리 코드를 배치하지 않는다. 왜냐하면 리듀서는 상태를 변경하는 기능만을 작성해야 하며, 순수 함수여야 하기 때문이다. redux-thunk는 액션 대신에 thunk라는 함수를 전달(dispatch)하도록 하여 비동기 처리를 수행하는 기능을 제공하는 미들웨어이다. 지연된 연산을 실행하기 위해 표현식으로 만든 함수라고 할 수 있다.
const asyncAction = createAsyncThunk("액션명", asnyc (arg, thunkAPI) => {
// arg는 비동기 처리할 때 필요한 아규먼트
// 비동기 처리 후 마지막에 리턴 하는 값이 최종적으로 완료했을 때 전달하는 action의 페이로드가 된다.
return payload
})
createAsyncThunk 툴킷 함수의 특징은 시점별로 직접 dispatch(action) 하지 않아도 된다는 것.
리턴 받은 함수의 이름이 asyncAction
이고 액션명이 searchPerson
으로 지정했다면 각 시점의 액션 생성자 함수와 액션이 사용하는 액션명은 아래와 같다.
시점 | 액션명 | 액션 생성자 함수 |
---|---|---|
비동기 작업 시작 | searchPerson/pending | asyncAction.pending |
비동기 작업 완료 | searchPerson/fulfilled | asyncAction.fulfilled |
비동기 작업 실패 | searchPerson/rejected | asyncAction.rejected |
createAsyncThunk() 람수에 전달되는 두 번째 인자인 payloadCreator 함수는 Promise 기반이므로 async/await이나 Promise 기반으로 작성해야 한다.
백엔드 API 요청 redux-thunk와 axios 사용하기
새해가 되고 나서 시간이 더 빠르게 가는 것만 같다! 미니 프로젝트를 처음 받았을 때는 빨리 끝낼 수 있다고 생각했는데 막상 시작하고 나니 신경 쓸 것도 많고 내가 하고 싶은 것들도 많아져서 더 많은 노력을 해야 될 것 같다. 내가 조장이 아닌 조는 상상할 수 없다는 수강생들의 말을 들으면서 내가 더 잘하고 팀장으로서 노력을 해야 되겠다는 생각이 절실했던 한 주였다. 그리고 목요일에 진행한 멘토링에서 면접과 관련해서 많은 이야기를 들을 수 있어서 도움이 됐다. 요즘 포트폴리오 어떻게 작성하면 좋을지 고민 중인데 아직 방향성이 제대로 잡힌 건 아니지만 그래도 포트폴리오를 만들면서 도움이 될 것 같았다. 그리고 면접에서 받은 CS 질문 관련해서도. 기초적인 질문이지만 기억해 두지 않으면 자주 까먹는 것들인 것 같았다. 아좌좍.
지금까지 23주차의 기록을 읽어 주신 여러분, 감사합니다! 김당퀔은 이만 공부하러. 🥕🥕