미루다 미루다 드뎌 몰아서 올리는 Pre-Project 회고 모음,,🥲
pre-project는2022.08.19(금) ~ 09.06(화)
약 2주간StackOverFlow
사이트를 클론하는 토이 프로젝트다 🧸
비록 BE CRUD API가 2주 안에 나오지 않아서 기능은 모두 구현하지 못했지만, 팀 프로젝트를 진행해보면서 많은 것들을 배울 수 있었다!
노션에선 매일 정리해놓았던 회고록들 모아서 벨로그에도 기록쓰 ✍️
github test repository 생성 후에 PR, merge test를 진행했다.
git clone <repository url>
git branch <branch-name>
git add .
git commit -m ""
# pull 하기 전에 수정사항이 존재하다면 무조건 add, commit하기!
git pull origin dev
# pull 받고 수정 다 했으면
git add .
git commit -m ""
git push origin <my-branch-name>
PR
merge
오늘 URClass에서 스치듯 지나간
sprite
이미지에 대해서 직접 사용해봤다.
첨엔sprites.svg
파일을 어떻게 사용할지 몰라서 멍 때리다가 사용법 구글링하고 삽질한 끝에 Logo 넣기 성공 🫠
전에 스터디원분이 알려주신 🐮spritecow
사이트를 통해sprites.svg
파일에서 내가 원하는 부분의 이미지만 사용할 수 있었다.
svg 이미지 파일이 화질 안 깨진다고 배웠었는데 React에 적용해본건 이번이 처음이었따!
🐮 Sprite Cow
[sprites image 사용시 활용한 사이트]
// sprites 이미지 사용법
import LogoSrc from "../assets/sprites.svg"; // 사용할 sprites 이미지 import
// styled-components로 backgroud, width, height 설정해주기
// 여기 css는 spritecow에서 복붙해서 쓰면 된다!
const Logo = styled.div`
background: url(${LogoSrc}) no-repeat 0 100%;
width: 150px;
height: 30px;
`;
// svg 이미지 사용법
import { ReactComponent as Logo } from "../assets/logo.svg";
<Logo />
사이드바가 있는 페이지도 있고, 없는 페이지도 있어서 이걸 어떻게 라우터 설정을 해야 할지 팀원분과 고민을 해봤다,,🤔
이것저것 적용해보다가 구글링하던 도중 Router의 Outlet 속성을 이용하는 방법을 찾아서 적용해봤다!
// SidebarLayout.js
import { Outlet } from "react-router-dom";
const SidebarLayout = () => {
return (
<Container>
<SideBar />
<Outlet />
</Container>
);
};
// App.js
function App() {
return (
<div>
<Nav />
<AppContainer>
<Routes>
{/* SideBar O page */}
<Route element={<SidebarLayout />}>
<Route path="/" element={<Main />} />
<Route path="/ask" element={<Ask />} />
</Route>
{/* SideBar X page */}
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
</Routes>
</AppContainer>
</div>
);
}
README.md
update서버 통신 부분이 감이 안 잡혀서 어떻게 진행해야 할지 고민이 많아서 이 부분에 대해 찾아본 결과 아래 과정으로 진행하면 될듯?!
1. 프론트에서 json-server로 질문 등록, 조회, 수정, 삭제가 일단 되는지 확인
2. webpack 번들링 (svg 이미지 파일 까다롭..)
3. AWS S3 배포 (http://~)
4. + AWS CloudFront → https로 배포가능하며, 코드 안 보이도록 배포 가능
5. + AWS Route53 → 원하는 도메인 이름으로 배포 가능
6. BE한테 url 주소 알려주면 FE에서 AWS에서 진행하는 일은 끝 ~?!
프론트는 S3에서 배포하면 EC2에 따로 배포할 필요는 없음!
API 명세서도 BE랑 다시 이야기해봐야 한다.
보통 BE에서 아래와 같은 json 형식으로 데이터를 주고받을 때의 더미 데이터도 함께 API 명세서에 포함해서 주는듯? gitbook에다가 아래와 같이 상세히 정리해서 주시면 좋지만 벌써 일주일이 지난 시점에서 gitbook 사용법을 익히기에는 또 다시 시간이 지체될수도 있으니까 일단은 편하신 방식대로 해주셨으면 하는 바램,,
{
'title': 'spring rest docs api documantation',
'body': 'How to document top-level array as response payload with REST Docs',
'tag': ['java', 'spring']
}
./~
으로 수정)➕ webpack 번들링하고, CloudFront, Route53 사용해보기
주말에는 알바갔다가 와서 저녁먹구 피곤해서 밤까지 자버리고, 새벽에 코딩 좀 하다가 늦게 자구 일어나기를 반복했다,,
코드를 너무 막 짰더니 내가 짠 코드에서 원하는 부분을 찾을 때 복잡하다는 느낌을 많이 받았다.. 그래서 크기, 위치 같은게 내가 원하는대로 잘 안되서 스택오버플로우 사이트에서 개발자 도구로 사이트 코드 좀 뜯어 보고, 코드 구조를 조금 변경했다!
Zustand
공부 → axios
적용오늘은 진짜 한 결과물이 없다,, webpack도 끙끙대다가 생각한대로 잘 화면이 나오지 않아서 일단 내일의 나에게 미뤘고, zustand로 상태관리 해보는 곳에서도 생소해서 그런지 공부하고 적용해보는 곳에서 시간을 다 썼다,,,
뭔가 과연 플젝을 완성시킬 순 있을까라는 걱정때문인지 집중도 잘 안되서 뭔가 진전이 없었던 하루.. 🥲
zustand와 axios 개념이 잘 안 잡혀 있는 상태에서 무작정 플젝 코드에 적용해보려고 하니까 잘 안 되서 오늘도 몇시간째 삽질만,,
바보같이 json-server 사용할 때 json 파일 안에 id 값을 따로 안 줘서 post 요청시 값이 안 들어갔던거였다,;
그래서 아예 새로운 빈 리액트 플젝 파일에다가 input 상태관리부터 시작해서 zustand 적용하여 post 보내는 작업까지 차근차근 공부하면서 다시 진행중..!
엊그제부터 zustand 공부하고 적용해봤는데 잘 안되다가 오늘은 조금 진전이 되었다. zustand 내에서 axios get 요청은 되는데 post 요청이 잘 안되서 그냥 zustand 밖에서 사용했는데 팀원분이 말씀하신대로 수정하니까 zustand 안에서도 post 요청이 되었다!! 👍👍
근데 로그인은 어떻게 접근해야 할지 잘 모르겠음,, 계속 삽질했는데 오늘은 실패 😕 내일 다시 도전해보자!
// store.js
import create from "zustand";
import { devtools } from "zustand/middleware";
import axios from "axios";
const store = (set) => ({
data: [],
name: "",
email: "",
password: "",
setName: (name) => set({ name }),
setEmail: (email) => set({ email }),
setPassword: (password) => set({ password }),
isLogin: false,
loading: false,
hasErrors: false,
setIsLogin: (isLogin) => set({ isLogin }),
...
// zustand 내에서 axios post 요청하기
fetch: async (name, email, password) => {
set(() => ({ loading: true }));
try {
const response = await axios.post("http://localhost:3001/user", {
name,
email,
password,
});
set((state) => ({ data: (state.data = response.data), loading: false }));
console.log(response.data);
} catch (err) {
set(() => ({ hasErrors: true, loading: false }));
}
},
});
const useStore = create(
process.env.NODE_ENV !== "production" ? devtools(store) : store
);
export default useStore;
// signup.js
import React from "react";
import useStore from "../store";
function Signup() {
// zustand에서 전역으로 선언한 변수 가져다 쓰기
const {
name,
email,
password,
setName,
setEmail,
setPassword,
...
} = useStore((state) => state);
const fetchData = useStore((state) => state.fetch);
const onEmailChange = (e) => {
// 이메일 유효성 검사
// 정규표현식 사용
const emailRegex =
/^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/;
setEmail(e.target.value);
// 위의 이메일 정규표현식에 맞는지 검사
if (!emailRegex.test(e.target.value)) {
setEmailMessage("이메일 형식이 틀렸습니다. 다시 작성해주세요!");
setIsEmail(false);
} else {
setEmailMessage("올바른 이메일 형식입니다!");
setIsEmail(true);
}
};
const handleSubmit = async () => {
await fetchData(name, email, password)
.then(() => alert("회원가입이 완료되었습니다!"))
.then(() => navigate("/login"));
};
...
return (
<div className="App">
<div>Signup</div>
<div>
<input value={email} onChange={onEmailChange} />
<div className={`message ${isEmail ? "success" : "error"}`}>
{emailMessage}
</div>
</div>
...
<button
onClick={handleSubmit}
disabled={!(isName && isEmail && isPassword)}
>
Click
</button>
</div>
);
export default Signup;
// 추후 Token을 localStorage에 추가
localStorage.setItem("token", data);
// 추후 localStorage에서 Token 값 읽어서 다른 곳에서 사용하기
localStorage.getItem("token");
📎 [참고 자료] React - localStorage 브라우저에 데이터 저장하기
😵💫 오늘도 어제에 이어서 로그인 기능 삽질을 어마어마하게 했다. 코드스테이츠에서 로그인쪽 배울 땐 BE 부분을 중심으로 배워서 그런건지 프론트에 어디부터 어디까지 구현해야 하는지 감이 안 잡혔고, BE에선 어디까지 구현이 가능한건지 몰라서 많은 시간을 이쪽에 허비한 것 같다,, 새벽 내내 삽질하다가 다른 분의 어시스트로 약간 감은 잡았다.
🫠 아마 BE부분이랑 연결하고 나서 어떤 데이터가 넘어오는지 확인한 다음에 코드를 수정하던지 할 수 있을듯! 지금으로썬 여기까지 밖에 구현할 수 밖에 없는 듯하다.
🫥 json-server로 구현하려니 내 머릿 속 로직은 일단 프론트에서 로그인 입력창에 입력한 이메일, 비밀번호가 현재 json 파일에 있는 회원 정보와 일치하면 filter해가지고 일치하는 정보만 가져오면 된다고 생각했다. 근데 아마 BE에서 일치하는 회원정보만 넘겨 준다고 하는데 이것도 서로 통신해서 데이터 주고받아봐야 알 것 같은?
일단 json-server로 로그인 기능 구현하긴 했는데 로그인 입력창에서 한번 틀리고 다시 이멜, 비번 쳤을 때 뭔가 로그인이 한번에 성공하지 못하는 것 같다,, 새로고침하구 한번에 데이터에 있는 정보로 로그인 했을 때는 로그인 되긴 함,,; 추후에 코드 수정 필요!!
회원가입 api test
로그인 api test
- [BE] put → patch로 변경해야함 (질문, 답변 수정)
- put은 변경된 부분만 보내지는 반면, patch는 변경되지 않은 부분도 함께 보내진다..?
- 질문 상세 부분 api → get, patch, post 메소드가 다르므로 /question/{question_id} 요런 식으로 같은 api로 요청 괜츈
- 질문 조회 부분에서 question, user 정보 등 원하는 정보들 한번에 요청 → 프론트에선 요청만 하면 되고, 백에서 처리해줘야 함
- vercel 프론트 배포시 로그인, 회원가입 안됨.. → 아마 vercel 배포시 package.json이 반영이 안되서 프록시 설정이 안 먹히는듯? 그래서 vercel로 배포시엔 package.json까지 반영되도록 webpack 파일로 vercel 배포를 해야함
새로고침시 로그인을 유지하려면 App.js나 index.js에 token 값이 있으면 isLogin 상태를 true로 유지해주기
// 새로고침시에도 로그인 유지
const tokenInfo = localStorage.getItem("token");
useEffect(() => {
if (tokenInfo) {
setIsLogin(true);
}
}, []);
로그아웃
const logout = () => {
localStorage.removeItem("token");
setIsLogin(false);
alert("로그아웃되었습니다.");
};
🥲 내가 잘못하고 있었던 부분
오늘은 알바끝나고 저녁에 드뎌 회원가입과 로그인 부분 서버와 통신 test를 해봤다. 첨엔 어떻게 테스트를 해봐야 할까 막막했는데 proxy 설정해주고, url 부분 변경하니까 회원가입은 잘 받아와졌다. 회원가입 중복처리는 BE에서 구현이 안되어서 app.js에서 테스트 해보다가 렌더링될 때마다 회원가입이 되어서 300명 넘게 회원가입이 되어버린 셈이 되어버렸다,,😱
로그인쪽은 내가 너무 코드 로직을 엉망진창으로 짜놔서 필요없는 코드 정리하고, 로직 좀 수정해서 일단 토큰 값이 localstorage에 잘 담기긴 한다! 토큰 관리를 어떻게 효율적으로 할지는 좀 더 고민해봐야 할 문제..!
로그인까지는 되는데 그 뒤로 토큰을 이용해서 요청을 보낼 부분이 아직 백에서 준비가 안되서 할 일 없이 좀 방황하느라 한것도 없이 오늘 하루를 보낸듯 하다,, CSS나 코드 리팩토링 등 할건 많은데 왤캐 나태해질까나,,🥲
오늘도 딱히 한게 없는 무의미한 하루,,😿 일단 지금까지 한거 프론트 배포 S3 다시 해봤는데 CORS 에러가 나서 회원가입, 로그인도 안된다,, 어느 팀은 백에서 처리해줬다고 하고, 어떤 팀은 vercel에서 설정 좀 하고 나니까? 해결했다구 하고, 어떤 블로그 보니까 CloudFront 사용해서도 해결이 가능하다고 하는데 일단 CloudFront 사용해서 해결해봐야겠다..!
🫠 리더보다는 팀원으로써의 역할에 많이 익숙했던 내가 얼렁뚱땅 생각치 못하게 팀장이 되어 팀을 이끌어 나갔다,, 말하는 것보다는 듣는 것을 좋아하구, 리더쉽이 부족해서 회의 등을 진행할 때 조금 힘들긴 했지만 많은 것을 배울 수 있었다..!
BE에서 CRUD쪽이 미처 준비가 다 되지 못해서 비록 회원가입, 로그인만 된 채로 프리플젝 개발 기간이 종료되었지만, BE과 어떻게 소통하고 무엇을 요구해야 하는지 등 협업에 있어서 어떻게 해야 하는지 감을 잡을 수 있어서 유의미한 프로젝트 기간이었따 🙃