npm run dev 명령어를 back폴더 터미널에서 실행해서 서버 활성화 해주기
alecture 폴더에서도 npm run dev 명령어 다른 터미널에서 실행
회원가입 페이지
반복되는 코드는 커스텀 훅으로 간단화 할 수 있다.
hooks 경로에 useInput.ts 파일 만든다.
import { Dispatch, SetStateAction, useCallback, useState, ChangeEvent } from 'react';
//ts 매개변수 제네릭타입추론
type ReturnTypes<T> = [T, (e: ChangeEvent<HTMLInputElement>) => void, Dispatch<SetStateAction<T>>];
const useInput = <T>(initialData: T): ReturnTypes<T> => {
const [value, setValue] = useState(initialData);
const handler = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setValue((e.target.value as unknown) as T);
}, []);
return [value, handler, setValue];
};
export default useInput;
<TS> - 매개변수, 리던 값의 타입을 선언하지 않으면 에러가 난다. 이때 any 또는 T를 사용하여 타입을 설정할 수 있다.
- 커스텀 훅 hook 사용시 index.tsx 코드
import useInput from '@hooks/useInput';
const [email, onChangeEmail, setEmail] = useInput('');
const [nickname, onChangeNickname, setNickname] = useInput('');
axios, CORS 에러
redux를 사용하면, 코드가 길어지고, 재사용의 어려움이 있음. API 설계문서를 보고 요청값을 파악해아함.
서버로 요청을 보낼때는 콘솔이 아닌, 네트워크탭을 확인하는게 우선!
서버 요청보내는 코드
const onSubmit = useCallback(
(e) => {
e.preventDefault();
if (!mismatchError && nickname) {
console.log('서버로 회원가입하기');
//비동기 요청직전 초기화
setSignUpError('');
setSignUpSuccess(false);
axios
.post('http://localhost:3090/api/users', {
email,
nickname,
password,
})
//성공하는경우
.then((response) => {
console.log(response);
setSignUpSuccess(true);
})
//실패하는경우
.catch((error) => {
console.log(error.response);
setSignUpError(error.response.data);
})
//모든 경우 실행.
.finally(() => {});
}
},
[email, nickname, password, passwordCheck, mismatchError],
);
- Promise<AxiosResponse<any>>, try{} catch(error) 둘다 finally 사용 가능
포트넘버가 다른 프론트와 서버가 통신할때 발생하는 에러 CORS (둘다 localhost일경우)
- 배포 후에는 사용하지 않는다
https://bohyeon-n.github.io/deploy/web/cors.html
- 프론트엔드 개발자가 해결하는 방법 -> webpack.congif.ts 웹팩 devServer에 proxy를 설정해주면 해결할 수 있다!
proxy: {
'/api/': {
target: 'http://localhost:3095',
changeOrigin: true,
},
},
- 프론트엔드에서 api로 시작하는 요청은 3095 서버로 보내겠다고 선언해주는 것, 웹팩 코드 수정 후 서버 재시작
- axios 요청 url에 'http://localhost:3095/' 대신 다음과 같이 '/api/'를 넣어서 작성
- error.response.data
로그인 페이지 만들기
a href 대신 Lint to를 이용해 react-route-dom 사용하기
로그인되어있는 상태 푸는 방법? 쿠키삭제
1. 백엔트 서버를 껐다키는 방법
2. Application탭 connect.sid(세션 쿠키 이름, 언어마다 로그인메모리 이름 저장 달라짐) -> 지우면 로그인상태 해재 = 로그아웃
swr 쿠키 공유, 사용하기
로그인을 성공하면 서버에 있는 내 정보를 프론트에 보여줌, 로그아웃하면 정보를 버림
전역적으로 정보를 상태관리하는 전역 storeage 역할
GET요청을 보내서 받아온 데이터를 저장함
- alecture -> npm i swr
const { data, error, revalidate, mutate } = useSWR('/api/users', fetcher);
- useSWR('주소', fetcher) : 주소를 fetcher로 옮기고, fetcher 안에서 처리
util경로 안에 fetcher.ts 파일 생성해서 작성
import axios from 'axios';
const fetcher = (url: string) =>
axios
.get(url, {
withCredentials: true,
})
.then((response) => response.data);
export default fetcher;
- 주소가 매개변수로 넘어오고, axios.get 요청을 보내고, .then으로 응답을 받아 data 돌려줌 (response.data)
- 서버, 프론트 localhost 도메인이 다르면, 쿠키생성에 오류가 생김. -> withCredentials:true
-- withCredentials : true 설정 작성위치 GET은 2번째 자리, POST는 3번짜 자리
//index.ts Login
...
axios
.post(
'/api/users/login',
{ email, password },
{
withCredentials: true, //쿠키생성
},
)
...
-- 쿠키는 백엔드에서 생성을 하면, 프론트 브라우저가 기억을 하고, 매 요청마다 쿠키를 전송하는 역할
워크스페이스, 로그아웃
children props (<TS> FC 타입) : 다른 컴포넌트 안에 넣은 JSX
- Layout을 만들어서 Component를 전달해야 하는 경우, Content만 변경하는 것이다.
이러한 리턴에 대한 조건은 항상 hooks 보다 아래 위치해야함
//탭페이지 이동시 화면 깜빡이는 현상 방지
if (data === undefined) {
return <div>로딩중...</div>;
}
// 로그인 성공하면 channel 탭으로 이동
if (data) {
return <Redirect to="/workspace/sleact/channel/일반" />;
}
SWR 활용법 - optimistic ui
revalidate : 서버로 요청 다시 보내서 데이터를 다시 가져옴
mutate : 서버에 요청 보내지 않고, 데이터를 수정. SWR에서도 사용할 수 있음. 나중에 한번에 데이터점검
- shouldRevaildate: true|false(서버검사없음) : 인스타그램 즉각적 하트반응 -> 서버처리과정 생략하고, 화면에 바로 띄워줌. 나중에 요청 보내고, 오류가 발생하면 하트 꺼버림. =optimistic ui
- 낙관적인 optimistic ui : 요청이 성공할 것이라 가정하고 요청의 결과를 보여줌 -> 사용자 경험에 긍정적인 영
- pessimistic ui : 기본요청처리방식
느낀점
매일 어려움을 겪었던 axios에 대해 직접 다루는 강의를 보니,, 이젤 할수있을 것 같다는 근자감이 생김
토큰으로 localstorage에 저장하는 로그인 방식을 다루어 보았는데, 서버와 소통하고, swr로 프론트에서 지속적인 상태관리를 하는 기능이 신기했고, 더 자세히 알아보고 싶다. 플젝에 적용하고 싶기 때문에 코드를 많이 뜯어봐야겠다!
작업시 CORS 에러 처리방법 등 꿀팁을 알게 되었다
알게 된 것에서 그치지 말고 기억하고 개발에 적용하자!