지난 1주와 요번 한주를 통합으로 정리하는 글입니다
프리프로젝트 마무리에서의 배운점과 메인프로젝트 시작하며 진행상황에 대해 작성하려합니다
코드스테이츠 엔지니어링 시작 21주차
- pre - project 마무리 ( 20주 )
- main - project 시작 ( 21주 )
pre- project ( stackoverflow 클론 )
https://github.com/insidelamp/seb40_pre_019
GitHub - insidelamp/seb40_pre_019
Contribute to insidelamp/seb40_pre_019 development by creating an account on GitHub.
github.com
완성화면
메인페이지


회원가입, 로그인


질문추가 , 질문 수정, 질문 삭제



답변조회, 답변추가, 답변수정, 답변삭제




클라이언트 배포 & 백엔드 배포
요번 프로젝트에서 클라이언트는 S3에서 배포를 진행하였습니다
로컬에서 테스트할때는 CORS를 우회하는 proxy설정을 하여 테스트를 진행하였습니다
이후 S3에서 클라이언트 배포를 진행하였고 CORS에러를 발견하여 프록시 설정으로 CORS를 우회하려하였습니다
로컬에서 proxy설정대로 똑같이 했지만 에러가났고 이를 해결하기위해서 찾다보니 2가지의 방법이 나왔습니다
- 백엔드에서 CORS를 해결하는방법
- 클라이언트 배포를 S3 를 이용해서가아닌 proxy설정이 되는 버셀로 배포
10시간정도 배포를 시도해보았지만 해결되지않았고 저녁 9시쯤 2시간만 더해보고 정안되면 버셀로 배포하는방법으로 결정하였습니다
2시간안으로 백엔드 CORS 해결하는방법에대한 결과가 나와 클라이언트와 연결이 성공했지만 에러등을 만나게 됬습니다
이후 새벽까지 클라이언트 에러 해결을 진행하였고 다음날 아침 한시간을 더 진행하여 완료를 지었습니다
요번 배포를 진행하면서 로컬에서의 테스트와 배포환경에서의 테스트가 많이 틀리다는것을 알게되었고 이후 배포주기를 조금더 짧게가져 테스트를 진행해야한다는것을 알게되었습니다
코드변경하여 깃허브 배포예정
위의 사진의 경우 배포를 진행하고 찍었으며 현재 코드를 수정하여 기능이 동작할수있도록 코드를 바꿔 깃허브 페이지로 배포하여 통신을 할수있게끔 만들어 배포를 진행하려합니다
main - project ( 유통과 관련된 사이트 만들어보기 )
사용하려는 프레임워크들
- React
- axios
- redux-toolkit
- styled-components
제가 맡은 파트는 로그인, 회원가입, 로그인 유지 , 상세페이지입니다
만들고있는 페이지 화면들




팀원들과 같이 만들어본 피그마
https://www.figma.com/file/LiocYYEWG2dZbFTqhCF8Z8/figma-team-library?t=Pne8HVvwayPMTnN9-1
Figma
Created with Figma
www.figma.com
프리프로젝트에서 사용한 리덕스 툴킷의 정보에대해 공부해봤습니다
store.js
import { combineReducers, configureStore } from "@reduxjs/toolkit";
// configureStore = 리듀서에 반환된 새로운 store를 객체로 정리해 관리하는곳
// redux의 createStore와 비슷하지만 다른점은 Thunk, dev toll 까지 까지 자동으로 등록해줌
// 현재 createStore는 사용은하지만 책임을지지않는다? 라고나옴
// 리덕스 리듀서를 작성할때 가장 일반적인 용례를 단순화 하는 유틸리티 함수 라고 redux홈페이지에 나와있음
// 일반적인 용으로는 모든 리듀서를 호출하거나 묶여있는 ( 래핑된 ) 모든 슬라이스 리듀서를 호출하는역할을함
// 아래의 경우 articleSlice와 userSlice를 하나로 묶어서 사용하기위해 사용됨
import articleSlice from "./slices/articleSlice";
import userSlice from "./slices/userSlice";
// 임포트하여 combineReducers로 하나로 묶어줌
// conbineReducers 로 하나로 래핑한 방법
const rootReducer = combineReducers({
article: articleSlice,
user: userSlice,
});
const store = configureStore({ reducer: rootReducer });
export default store;
//하나로 래핑하지않고 개별로 사용하는방법
/*
const store = configureStore({
reducer: {
article: articleSlice,
user: userSlice,
},
});
export default store
*/
userSlice.js
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import Apis from "../../apis/apis";
/*
//createAsyncThunk 쓰는이유
createAsyncThunk 는 createAction 의 비동기 버전을 위해 고안되었습니다.
redux 에서 비동기 처리를 할경우 보통 thunk, saga, redux-observable 등의 미들웨어를 사용하여
한개의 비동기 액션에 대해 pending(비동기 호출 전), success(비동기 호출 성공), failure(비동기 호출 실패) 의
상태를 생성하여 처리하는 경우가 많았습니다.
이때 각 상태를 만드는것은 각자 유틸 패키지를 받거나 직접 구현하여서 사용하였는데
이를 redux-toolkit 에서 createAsyncThunk 을 통해 지원합니다.
createAsyncThunkfmf 를 선언하게되면 첫번째 파라미터로 선언한 엑션 이름에
pending, fulfilled, rejected의 상태에 대한 action을 자동으로 생성해주게됩니다
또한 AbortController를 지원하기 때문에 thunk를 사용하여도 api에 대한 취소 작업이 가능합니다
// AbortController
AbortController는 웹요청을 취소할 수 있게 해주는 기능입니다
보통 웹에서 요청을 보내면 이후에 필요 없어져도 취소할방법이 없어
그냥 요청은 그대로 두고 응답받은 내용을 사용안하는 식으로 구현했습니다
간단한 HTTP 요청은 응답이 빠르기때문에 괜찮을수있지만 무거운 요청의 경우
불필요한 네트워크 트래픽을 낭비하게 되거나 연결을 차지하고 있으므로 취소하는것이 좋습니다
모든 메이저 브라우저에서 지원하고있기때문에 사용하기가 수월해진다고 합니다
=====================================================================================
slice 객체는 {name , initialState, reducers, extraReducers }로 구성되어있습니다
name: string을 넣어서 prefix ( 접두사 )로 사용
initialState: 기본상태가 들어갑니다
reducers: slice 안에서 사용할 reducer 들을 만들수 있음, 해당 reducer들을 만들면
자동으로 slice.action에 reducers에서 만든 reducer에 대한 actionCreator 함수가 들어 있음
extraReducers: slice에서 만들어진 reducers에 의한 action, reducer가 아닌 외부에서 만들어진
action을 통해 현재 slice에서 사용하는 initialState에 변경을 가하는 경우 처리받는 reducer
(비동기 작업 함수 처리 등 ( createAsyncThunk )에 사용됨)
*/
export const signUser = createAsyncThunk(
"user/signUser",
async ({ signData, navigate }) => {
return Apis.post(`/users/login/`, signData)
.then((res) => {
navigate("/users/login");
return res.data;
})
.catch((err) => {
console.log(err);
});
}
);
export const loginUser = createAsyncThunk(
"user/loginUser",
async ({ loginData, navigate }) => {
return Apis.post(`user`, loginData)
.then((res) => {
console.log(res);
navigate("/");
return res.data;
})
.catch((err) => {
console.log(err);
});
}
);
/*
// createSlice 쓰는 이유
createSlice는 action과 reducer를 간단하게 생성해주는 녀석입니다
immer의 produce를 자체적으로 지원해주기떄문에 state를 직접 변경할수있습니다
immer 란 불변성 유지를 도와주는 라이브러리입니다
// 불변성 유지
여기서의 불변성 유지 ( 상태를 변경하지 않는것 )란
리액트에서는 state를 직접적으로 변경하지말라는 말이있습니다
리액트는 기본적으로 부모로부터 내려받은 props나 내부상태인 state가 변경되었을때 컴포넌트를 다시 그려주는 리렌더링 과정이 일어납니다
리액트는 props와 state의 변경을 불변성을 이용해 감지합니다
객체의 참조를 복사하는점을 이용해 단순히 참조만 비교하는 얕은 비교를 이용해서 변경이 일어났는지 확인합니다
// immer
immer의 핵심원리는 Copy-on-write (기록중 복사) 와 Proxy(프록시)에 있습니다
기록중 복사란 자원을 공유하다가 수정해야할 경우가 발생하면 자원의 복사본을 쓰게하는 갠며입니다
immer는 프록시 객체를 이용해서 원본 객체인 상ㅌ 객체대신 프록시 객체를 대신 조작(변경)하는것입니다
// produce
immer에서 우리가 쓸 함수는 오직 produce만 알면 됩니다
produce란 2가지의 파람을 가져오고 첫번째는 수정하고 싶은 객체/배열, 두번째는 첫번째 파라미터에 할당된 객체/배열을 바꾸는 함수입니다.
*/
const userSlice = createSlice({
name: "user",
initialState: {
users: [],
loading: false,
error: "",
},
reducers: {},
extraReducers: {
[signUser.fulfilled]: (state, action) => {
state.users = action.payload;
state.loading = true;
state.error = "";
},
[loginUser.fulfilled]: (state, action) => {
state.users = action.payload;
state.loading = true;
state.error = "";
},
},
});
// reducer는, 현재의 상태와, 전달 받은 액션을 참고하여 새로운 상태를 만들어서 반환합니다.
export default userSlice.reducer;'프로그램 시작후 각 주차 정리' 카테고리의 다른 글
| 공부 38주차 코드 스테이츠 (21주 ~ 24주 ) 메인프로젝트 완성도중 디버깅 정리 - version 2 (0) | 2022.11.27 |
|---|---|
| 공부 38주차 코드 스테이츠 (21주 ~ 24주 ) 메인프로젝트 완성도중 디버깅 정리 - version 1 (0) | 2022.11.24 |
| 공부 30주차 코드 스테이츠(16주) - Virtual Dom , Custom Component (0) | 2022.10.08 |
| 공부 29주차 코드 스테이츠(15주) - React번들링과 웹팩 , React 심화 (0) | 2022.10.03 |
| 공부 28주차 코드 스테이츠(14주) - Section 3 회고 및 자료구조 및 알고리즘 / HTML & CSS 심화 (1) | 2022.09.25 |