-
Notifications
You must be signed in to change notification settings - Fork 0
스터디 내용 작성
- 컴포넌트 상태관리, 상태가 변경 될 때 화면을 다시 렌더링해야하는 모든 경우에 사용
📌 꼭 써야하는 상황 -> 컴포넌트 상태가 사용자의 상호작용이나 데이터 fetching 등 특정 이벤트에 의해 변경되고, 그 변경된 값이 화면에 즉시 반영되어야할 때
-
폼 입력값 관리 : 회원가입, 로그인, 글쓰기 등 사용자가 입력하는 아이디, 비밀번호, 이메일 등 값 관리 시 사용
-
UI 상태관리 : 모달 창의 열림/닫힘 상태, 탭 메뉴의 활성화 상태, 아코디언 메뉴의 펼침/접힘 상태 등 사용자의 행동에 따라 UI가 바뀌어야 할 때 사용
-
데이터 Fetching 후 상태 관리 : 서버로부터 받아온 데이터를 화면에 표시해야할 때 사용. 로딩중, 성공, 실패와 같은 데이터 fetching 상태 관리시에도 유용
-
카운터 및 토글 : 버튼 클릭시 숫자를 증가/감소 시키거나 , 스위치를 켜고 끄는 등 간단한 상호작용 구현시 사용
📌 불필요한 상황 -> 컴포넌트가 다시 렌더링 될 필요 x, useState 특성으로 인해 불필요한 성능 저하 유발가능 경우 피하는게 좋음
-
단순변수 : 컴포넌트가 리렌더링 되어도 값이 유지될 필요가 없는, 함수의 사용되는 임시 변수는 useState로 선언할 필요가없음. 일반적으로 let이나 const로 선언하면 됨
-
리렌더링이 불필요한 값 : 값이 변경되어도 화면이 바뀔 필요가 없는 경우, useState 대신 useRef를 사용하는 것이 효율적. useRef는 값이 변경되어도 리렌더링 x(스크롤 위치 기억, 이전 상태 값 저장, DOM요소에 직접 접근 시)
-
전역상태 관리 : 여러 컴포넌트에서 공유하고 사용하는 상태(예시,로그인한 유저 정보, 테마설정)을 useState만으로 관리하면 'Props Drilling'(상태를 계속해서 자식 컴포넌트로 내려주는 것) 문제 발생가능, 이경우 Context API, Recoil, Zustand, Redux와 같은 상태관리 라이브러리를 사용하는 것이 더 좋음
-
컴포넌트 외부에서 관리되는 값 : 컴포넌트의 렌더링 주기와 상관없는 라이브러리의 인스턴스나 전역객체 등은 useState로 관리할 필요가 없음
- 전역상태관리
- 공용창고를 만드는 방식
- 도구 : Redux, Recoil, Zustand or Context API& useReducer
- 작동 방식 : 입력 데이터를 공용 창고에 넣어두고, 다음 페이지에서 데이터를 꺼내어 사용
- URL쿼리 파라미터 이용
- 입력된 데이터를 주소에 실어 보내기
- 민감정보거나 데이터가 많으면 비추천
- 사용자가 뒤로 가기/앞으로 가기 할때, 브라우저가 파라미터들을 기억하여 상태복원(검색결과 및 필터링 값 공유, 페이지네이션, 임시적인 식별자 전달_로그인안한상태에서 장바구니에 물건 담았을때)
- 브라우저 저장소 이용
- 도구 : sessionStorage(브라우저 닫으면 사라짐) localStroage(영구저장)
- 영구저장은 다크모드설정, 언어설정, 다시보지않기 설정, 자동로그인을 위한 토큰저장시사용(나갔다 들어와도 설정값을 기억하여 편의성 증가 )
- sessionStroage는 작성중인 글, 방금봤던 광고 팝업 상태 등에서 사용 됨
- 빠른접근성으로 서버에 매번 안물어봐도 사용자 컴퓨터에서 바로 정보르르 가져와 사이트 로딩 속도를 높임
useState를 사용하여 UI제어 및 인력 값 트래킹을 위해 사용
const [loginid, setLoginId] = useState('');
-> loginid는 값을 읽을 때 사용하는 이름 (상태 변수, 현재값을 담고있는 상자. 읽기전용이라 변경 불가)
-> setLoginId 를 사용해야만 새로운 값으로 변경가능(업데이트 함수, 그 상자안의 값을 바꾸는 버튼, 쓰기전용이라 새 값을 인수로 넣어주면 상태변경 됨)
-> useState('') 는 초기값. 처음 생성시 아무것도 없다는 것을 의미하기 위하여 빈 값으로 둠 (false, true 들어갈 수 있음)
const [isCodeSent, setIsCodeSent] = useState<boolean>(false);
-> boolean 타입만 들어갈 수 있도록 명시
상태선언은
const [상태 이름, set상태 이름] = useState(초기값);
dispatch는 Context API 와 함께 useReducer 패턴으로 구현된 전역상태 업데이트 함수. 상태를 불변성있게 관리하며 단방향 데이터흐름을 유지. 1페이지 데이터를 Context Stroage에 저장하여 2페이지 컴포넌트가 데이터 참조가 가능하도록 상태를 영속화 함.
dipatch({ type: '액션 이름' payload: 바꿀 정보 });
액션타입
| RESET_FORM | UPDATE_FORM_DATA | SET_FIELD | SET_ERROR |
| 모든 정보를 처음으로 되돌리기 | paload에 담긴 데이터를 기존 상태에 병합하라는 명령 이름 ,규칙 식별자 | 하나의 정보만 변경 | 전역적으로 중요한 에러 메시지 저장 |
| 회원가입 최종 성공, 사용자가 회원가입을 취소할 때 사용 | 한 필드만 업데이트, 복잡하지않은 간단한 상태 변경시 사용 | 서버 인증 과정 중 발생하는 에러를 전체 앱에 공유해야할 때 사용 |
✏️Context 를 구현할 때 정의했던 Reducer함수 내부의 switch 문에서 사용 -> Reducer(Context 저장소 담당)는 dispatch가 보낸 액션이 도착하면 다음과 같이 동작
(e:React.ChangeEvent<HTMLInputElement>)
-> input 요소의 값이 변경 될때 발생하는 합성 이벤트를 인자로 받음. HTMLInputElemet 가 관련된 이벤트임을 명시
const value = e.target.value; setLoginId(value);
-> 이벤트 객체 (e)의 target 속성에서 현재 입력된 값 추출 (input 박스에 작성된 값을 value에 옮겨 담기)
Hooks API를 통해 loginid 상태를 비동기적으로 업데이트
setIsLoginIdChecked(false)
-> 입력값이 변경되면 기존 중복 검증결과 무효처리. 재검증 유도를 위해 false로 리셋
if (!/^[a--zA-Z0-9]*$/.test(value))
-> 정규 표현식을 사용한 형식 유효성 검사. 문자열의 시작(^)부터 끝($)까지 영문 대소문자와 숫자만 포함해야 함을 의미
사용법 -> onChange속성에 이벤트 핸들러로 바인딩
const handleSendCode = async (e: React.MouseEvent) => { ... }
-> 비동기 작업을 포함하는 React 마우스 클릭 이벤트 핸들러.
e.preventDefault(); 을 호출하여 폼 제출과 같은 기본 이벤트 동작 방지
setVerificationError('');
-> 이전 요청 에러상태 초기화
const res = await axios.post('/api/auth/signup', { phonenumber });
-> axios 라이브러리를 이용하여 POST 요청. 서버 주소 엔드포인트에 phonenumeber를 요청 본문에 담아 비동기적으로 전송
if (axios.isAxiosError(error) && error.response)
-> 에러가 axios 통신 과정에서 발생했으며 서버로부터 응답을 받은 경우 확인.
error.response.data 를 통해 서버가 보낸 구체적 에러 메시지를 콘솔에 로깅
사용법
- useState훅을 통해 상태가 정의되어있어야함
- 휴대폰 번호상태
- 인증번호 발송여부(재전송 확인용)
- 에러메시지 상태 등
- 인증번호 발송 버튼에 onClick이벤트에 보통 연결됨
-
데이터 및 상태 정의 -> value 값과 erd 값 맞추기, useState로 미리 정의된 값 사용
-
통신 방법 및 규칙 정의 (백/프론트 협의) -> HTTP 메서드 정의, CRUD에 맞는 메서드 정의 -> API 주소 설정하기 (각 기능별 엔드포인트 주소 확정, 프론트엔드에서 사용할 주소를 명확히하기 -> 요청(Reques)시 보낼 데이터 구조와 필수값 확정, 응답 (Response)로 받을 데이터의 구조와 성공/실패 메시지 확정 -> 에러코드 및 형식 확정(HTTP상태코드를 백엔드로부터 받아서(4xx,5xx) 에러메시지 JSON 형식 정의)
-
인증/인가 -> 로그인 후 사용자 식별을 위해 JWT토큰을 사용할지, 세션/쿠키를 사용할지 확정하고 토큰 저장소 결정 -> 헤더 설정 정의 (API 요청시 인증토큰을 HTTP헤더의 Authorization 필드에 어떻게 넣을지 (Bearer<토큰>) 정의
-
환경설정 및 연동 구조 -> 프록시 설정 (개발 환경에서 CORS 문제 해결을 위해 next.config.js 파일에 rewriters 설정 완료
인터넷상의 집 주소 -> 백엔드에서 처리
API를 설계, 구축, 문서화 및 사용하는데 도움을 주는 도구 및 기술
데이터베이스에 저장될 데이터의 구조와 관계를 시각적으로 표현한 것
JSON Web Token의 약자로, 웹앱에서 인증과 정보교환을 위해 사용되는 전자 서명 된 토큰 사용자가 로그인했을 때 서버가 발급하고, 브라우저(클라이언트) 가 이를 저장했다가 API 요청시 서버에 함께 보내 본인임을 증명하는데 사용
| 메서드 | GET | POST | PUT | PATCH | DELETE |
| RESTfull용도 | READ(조회) | CREATE(생성) | UPDATE(전체수정) | UPDATE(부분수정) | DELETE(삭제) |
| 사용목적 | 서버의 특정 자원이나 목록을 가져올 때 사용, 서버상태변경X | 서버에 새로운 자원 생성,매 요청마다 새로운 자원 생성 가능 | 특정 자원을 완전히 새로운 데이터로 덮어쓸 때, 같은요청 여러번 보내도 결과는 동일 | 특정 자원의 일부 필드만 수정 할때. PUT보다 효율적 | 서버의 특정 자원을 제거할때, 같은 요청 여러번 보내도 최종결과는 삭제된 상태로 동일 |
| 데이터전송방법 | URL파라미터(필터링,정렬기준 등) | Body(생성할 자원의 데이터,회원가입 정보 등) | Body(자원의 모든 필드 데이터) | Body(수정할 필드와 값만 포함) | URL파라미터(삭제할 자원의 ID) |
아이디 중복요청, 닉네임 중복 요청 등 민감 정보를 요청해야하는경우 파라미터 값으로 보내는 GET요청 보다는 POST를 주로 사용함
A. URL 파라미터
-
주로 GET이나 DELETE요청시, 서버가 어떤 자원을 처리해야할지 식별하거나 추가적인 옵션을 제공할 때 사용
-
데이터가 URL에 노출 되므로, 비밀번호 같은 민감정보는 사용 안함
-
유형 a. 쿼리 파라미터
- URL 끝에 ?를 붙이고 key=value 형태로 전송. 여러개는 &로 연결
- 예시 : /products**?category=shoes&limit=10** (상품 목록 필터링/페이징)
b.경로 변수(Path Variable)
- URL의 경로 자체에 값을 포함하여 자원을 식별
- 예시 : /users/12345 (ID가 12345인 사용자 조회)
B. 요청본문(Request Body)
- 주로 POST,PUT,PATCH요청시 , 서버에 새로 만들거나 수저할 데이터 덩어리를 보낼 때 사용
- URL에 데이터가 노출되지 않으며 크기 제한도 거의 없음
- 가장 일반적인 형식은 JSON
- PUT : 자원 식별자는 경로변수로 보내고 수정 데이터는 Body로 보냄. 값이 없어도 필드를 포함해야됨
- PATCH : 특정 자원의 데이터 중 일부 필드만 수정할 때 사용. 자원 식별바는 경로변수로 보내고 수정할 필드만 Body로 보냄
- DELETE : 경로변수로 보내고 보통 Body 사용 x
| 문법 | JavaScript(useState('') | TypeScript(useState('') |
| 차이 | 타입이 동적으로 결정됨 | 타입이 명시적으로 string 으로 고정 |
| 안정성 | 안정성은 낮지만 유연 | 안정성 높고, 오류 미리 찾기 가능 |
- 변수, 함수, 혹은 상태(State)값을 연결하려면 중괄호를 반드시 이용해야함
{}를 안쓴다면...
| 코드 | React 인식 방식 | 결과 |
| value ={username} | JS변수username에 저장된 실제 값 | 상태(State)와 인풋값이 연동되어 값이 변함 |
| value="username" | 'username"이라는 문자열 | 인풋 값은 항상"username"으로 고정됨 |
🔑 {}의 역할: JSX에서 JS사용하기
- React의 JSX문법에서 중괄호 {}는 일종의 이스케이프 문자역할을 함
- "이 따옴표 안의 내용은 HTML 텍스트가 아닌 실행해야할 JavaScript코드입니다" 라고 React에게 알려주는 유일한 방법
| 목적 | 코드 | 설명 |
| 변수 값 연결 | value = {username} | username 변수의 값을 인풋의 값으로 결정 |
| 함수 연결 | onChange={e => setName(e.target.value)} | onChange이벤트가 발생했을 때 지정된 함수를 실행 |
| 조건부 렌더링 | {isLoggendIn && 로그아웃 | isLoggedIn 이 참(True)일때만 을 렌더링 |
동적으로 변화하는 상태나 실행할 로직을 연결하려면 반드시 {}을 사용해야함
const nextConfig = { ... };
-> Next.js 설정 옵션을 담는 자바스크립트 객체
module.export = nextConfig
-> Node.js 환경에서 이 객체를 Next.js 프레임워크가 읽을 수 있도록 모듈로 내보내기
- rewrites 함수
async rewrites() {. . .}
-> Next.js 서버가 요청을 받은 후, 지정된 규칙에 따라 **요청 경로를 변경(재작성)**하도록 지시하는 비동기 함수
const backendUrl = process.env.BACKEND_URL;
-> .env 파일 등에 정의된 환경 변수의 값 읽어오기. 이 값은 백엔드 실제주소임. 보안상 클라이언트에 노출 X
if (!backendUrl) {...}
-> 백엔드 주소 환경 변수가 설정되지 않았을 경우를 대비한 안전장치. 콘솔에 경고 출력, 프록시 규칙 없이 빈 배열 [] 을 반환하여 Next.js서버의 정상 작동 보장
return [ {. . .} ]
-> 재작성 규칙의 배열 반환. 하나 이상의 규칙 정의
- 프록시 규칙 상세 정의
source: '/api/:path*'
-> 요청을 가로챌 경로 패턴 정의
api로 시작하는 모든 요청을 Next.js가 잡아냄. :path*는 /api/ 뒤에오는 모든 하위 경로를 변수로 캡처
destination
-> source에서 캡처된 요청을 실제 전달할 목적지를 정의
여러경로를 등록할 경우 {}에 담아 똑같이 정의해주면 됨
하나의 객체 상태로 관리하면 더 깔끔하고 확장성도 좋아짐
- 객체정의
- onChange 핸들러 사용 (범용 핸들러)
...prevData
-> 이 문법은 기존 formData의 모든 필드 복사하여 유지 하게 해줌
[name]: value
-> 이거로 name이랑 value값 연결 가능
(아이디 필드에서 입력시 name은 userId, 코드는 {userId :'입력된 값'}
: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
-> 이벤트 e 타입 명시적으로 지정. input, select 요소에서 발생한 값 변경 이벤트라는것을 알려줌
const { name, value } = e.target;
-> 실제로 발생한 HTML 요소를 가리킴
- 입력 필드에 연결
- handleSubmit에서 객체 전송 로직 추가
try { const response = await axios.post(ID_CHECK_ENDPOINT, { params: { loginId: loginId, } }); console.log('생성 성공:', response.data); } catch (error) { console.error('생성 실패:', error.response.data); }