프로토타입 패턴은 객체 생성 할때 리소스 비용이 발생하는데 이 비용을 최대한 절감하려는데 목적을 갖고 있는 패턴이다. 그래서 객체를 생성할때 새롭게 생성하는것이아니라 원형(프로토타입)을 복사하여 원형이 가지고있는 메서드나 프로퍼티를 가져와 사용할수있게 하는것이다.
[클라스기반]
객체 생성 전에 클래스를 정의하고 이를 통해 객체 인스턴스를 생성
[자바스크립트]
클래스 없이 객체를 생성 (리터럴과 생성자)
자바스크립트는 객체를 만들때 함수를 사용해서 만드는데 객체의 프로토타입을 복사해서 객체를 만든다.
모든 객체는 자기가 어디에서 복제가 되었는지 정보를 알고있다.
마치 객체 지향에서의 상속 개념처럼 부모 객체의 프로퍼티나 메소드를 상속받아 쓸수있다.
이를 위임 이라고도 부른다.
이런 부모 객체를 프로토타입 객체 또는 프로토타입 이라고 부른다.
그리고 부모 객체를 참조하는 것을 프로토타입 링크라고 한다.
컴포넌트의 Props가 없을때 기본값으로 props를 설정하게되면 데이터가 없을 경우 레이아웃이 깨지거나 오류화면이 나올것에 대비할 수 있다.
// 데이터가 없을때 기본값을 설정
.... ( 컴포넌트 아래 위치 ).....
Post.defaultProps = {
user_info: {
user_name: 'tester',
user_profile: 'https://newsimg.sedaily.com/2021/10/13/22SQ3131O5_1.jpg'
},
image_url: 'https://newsimg.sedaily.com/2021/10/13/22SQ3131O5_1.jpg',
contents: '오징어게임 재밌어요!',
comment_cnt: 10,
insert_dt: '2021-02-27 10:00:00'
}
최소단위 컴포넌트를 만들때 매번 하나하나 컴포넌트 안쪽의 내용을 다르게 작성하기 위해서 props를 사용하여 내용을 다르게 보여줄수가 있다.
# 우선 defaultProps를 사용해서 컴포넌트에서 사용할 상태의 초기값을 설정해 둔다.
Grid.defaultProps = {
children: null,
is_flex: false,
width: "100%",
padding: false,
margin: false,
bg: false
}
# styled-components를 사용해서 해당 props를 통해 동적으로 스타일을 적용 시킬 수 있도록 정의 할 수 있다.
const GridBox = styled.div`
width: ${props => props.width };
height: 100%;
box-sizing: border-box;
${props => props.padding ? `padding: ${props.padding};` : '' }
${props => props.margin ? `margin: ${props.margin};` : '' }
${props => props.bg ? `background-color: ${props.bg};` : '' }
${props => props.is_flex ? `display: flex; align-items: center; justify-content: space-between;` : '' }
# 만약 별도의 props를 내려받는다면 그 props에 해당하는 값에 따라 유동적으로 렌더링을 할 수 있게 받아준다.
const Grid = (props) => {
const { is_flex, width, padding, margin, bg, children } = props
const styles = {
is_flex,
width,
padding,
margin,
bg
}
return (
... 컴포넌트 렌더링 ...
# 상위에서 받아온 props는 컴포넌트가 렌더링될때 사용될 수 있도록 컴포넌트 내부에 작성한다.
return (
<React.Fragment>
<GridBox {...styles}> // spread 연산자를 통해서 속성 적용
{ children }
</GridBox>
</React.Fragment>
)
}
** 구글 OAuth 동작 방식 정리해볼것
쿠키, 세션 스토리지, 로컬 스토리지 사용법, 차이점 알기
로컬 스토리지 | 세션 스토리지 | |
---|---|---|
데이터 보관 | O (사용자가 지우지 않는 한) | X (윈도우, 탭 닫을시 내용 제거) |
사용용도 | 자동 로그인 | 일회성 로그인 |
주의사항 | 비밀번호와 같은 중요 정보는 절대 저장 X | 비밀번호와 같은 중요 정보는 절대 저장 X |
[1] 차이 정리
1. 쿠키의 단점을 보완해 HTML5에서 '웹스토리지'라는 기술 탄생.
1-1) 웹스토리지 : 로컬스토리지, 세션스토리지.
1-2) 웹스토리지는 Key와 Value 형태로 이루어짐.
1-3) 웹스토리지는 클라이언트에 대한 정보를 저장.
1-4) 웹스토리지는 로컬에만 정보를 저장, 쿠키는 서버와 로컬에 정보를 저장.
3-1) 로컬&세션스토리지
장점1 : 서버에 불필요하게 데이터를 저장하지 않는다.
3-2) 로컬&세션스토리지
장점2 : 용량이 크다. (약 5Mb, 브라우저마다 차이 존재)
3-3) 로컬&세션스토리지 단점 : HTML5를 지원하지 않는 브라우저의 경우 사용 불가
4-1) 쿠키 장점 : 대부분의 브라우저가 지원
4-2) 쿠키 단점1 : 매 HTTP요청마다 포함되어 api호출로 서버에 부담.
4-3) 쿠키 단점2 : 쿠키의 용량이 작음 (약 4Kb)
4-4) 쿠키 단점3 : 암호화 존재 x -> 사용자 정보 도난 위험
[2] 각 예 - 어떤 유형의 데이터를 어디에 저장하면 좋을까?
자동 로그인 -> 로컬스토리지
입력 폼 정보 -> 세션스토리지
비로그인 장바구니 -> 세션스토리지
다시 보지 않음 팝업 창 -> 쿠키
자바스크립트 객체 예시
let object = {
"A" : 1, "B" : 2, "name" : "wecode", "Key" : "Value"
}
[3] 값 가져오는 법
localStorage.A (Key == A)
localStorage.getItem("A")
sessionStorage.A (Key == A)
sessionStorage.getItem("A")
getCookie("A") (Key == A)
[4] 세팅하는 법
localStorage.A = 1 (Key == A, Value = 1)
localStorage.setItem("A", 1)
sessionStorage.A = 1 (Key == A, Value = 1)
sessionStorage.setItem("A", 1)
setCookie("A", 1, 7) (Key == A, Value == 1, 유효기간 == 7초)
yarn add redux react-redux redux-thunk redux-logger history@4.10.1 connected-react-router@6.8.0
리덕스 비동기 작업 시 원하는 시점에서 라우팅을 시키기 위해서 필요한 라이브러리
기존 BrowswerRouter에서 우리는 스토어에 셋팅한 history 정보로 라우팅을 하기 위해서 ConnectedRouter로 라우팅 컴포넌트를 감싸준다.
yarn add immer redux-actions
*** 리덕스 스토어 설정하는 부분의 흐름을 다시 이해해 볼 필요가 있다. (좀 어렵다!)
돌고돌아 아날로그 공부법인가..
redux-action, immer, connectedRouter를 붙이는 리덕스 설정 작업이 조금은 복잡해서
코드를 하나하나 외우기보단 큰 맥락에서 어떠한 요소들이 붙여지는지 흐름을 외울수 있도록했다.
결국은 기초과정에서 아주 심플한 리덕스를 사용하다가 점차 필요한 패키지들을 끼워넣는 작업에서 조금은
코드가 복잡해질수 있으나 설치한 패키지로 인해서 사용성이 높아진다.
import React from "react";
import {Route} from "react-router-dom";
import {ConnectedRouter} from 'connected-react-router'
import {history} from '../redux/configureStore'
import Header from "../components/Header";
import PostList from "../pages/PostList";
import Signup from "../pages/Signup";
import Login from "../pages/Login";
import {Grid} from "../elements";
function App() {
return (
<React.Fragment>
<Grid>
<Header></Header>
<ConnectedRouter history={history}>
<Route path="/" exact component={PostList} />
<Route path="/login" exact component={Login} />
<Route path="/signup" exact component={Signup}/>
</ConnectedRouter>
</Grid>
</React.Fragment>
);
}
export default App;
import firebase from 'firebase/app'
import 'firebase/auth'
로그인을 시도할때 사용자 계정이 유효한지, 비밀번호가 맞는지 확인하기 위해
내가 직접 데이터를 비교하는것이 아니라 firebase auth 로그인 기능 비동기 통신시에 실패 로직에 error code에 따라 사용자에게 로그인 실패 사유를 보여줄 수있다.
아래 링크는 인증 패키지중 AuthErrorCodes를 확인 할 수 있는 페이지이다.
https://firebase.google.com/docs/reference/js/auth?authuser=0#autherrorcodes
인증 상태 지속성 수정
firebase.auth().setPersistence 메서드를 호출하면 기존의 지속성 유형을 지정하거나 수정할 수 있습니다.
import { getAuth, setPersistence, signInWithEmailAndPassword, browserSessionPersistence } from "firebase/auth";
const auth = getAuth();
setPersistence(auth, browserSessionPersistence)
.then(() => {
// Existing and future Auth states are now persisted in the current
// session only. Closing the window would clear any existing state even
// if a user forgets to sign out.
// ...
// New sign-in will be persisted with session persistence.
return signInWithEmailAndPassword(auth, email, password);
})
.catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
});
Debounce
이벤트가 일어나면 일정 시간을 기다렸다가 이벤트를 수행하며 일정 시간 내에 같은 이벤트가 또 들어오면 이전 요청은 취소한다.
보통 Decounce는 검색어 입력 이벤트에 알맞다.
Throttle
일정 시간 동안 일어난 이벤트를 모아서 주기적으로 1번씩 실행
Throttle은 스크롤 이벤트에 알맞다.
yarn add lodash