Facts
Feelings
Findings
- ReactElement vs ReactNode
- ReactNode, ReactElement는 typescript에서 컴포넌트에 타입을 부여할 때 사용된다.
- 클래스형 컴포넌트: render 메소드의 return 타입이 ReactNode
- 함수형 컴포넌트: return 타입이 ReactElement
ReactElement
interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
type: T;
props: P;
key: Key | null;
}
ReactNode
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
interface ReactNodeArray extends Array<ReactNode> {}
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
- ReactNode는 ReactElement의 superset.
- ReactNode는 ReactElement일 수 있고 null, undefined, boolean.. 좀 더 유연한 타입 정의!
references
- 자바스크립트 배열 초기화 ```javascript const twoDimArr1 = Array.from({length: 5}, () ⇒ Array.from({length:5}, () ⇒ false));
const twoDimArr2 = new Array(5).fill(new Array(5).fill(false));
- Array.from(): 유사 배열 객체(array-like object)나 반복 가능한 객체(iterable object)를 얕게 복사해 새로운 **Array** 객체를 만든다.
```javascript
console.log(Array.from('foo'));
// expected output: Array ["f", "o", "o"]
console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]
const arr = Array.from({length: 5});
const buttons = document.getElementsByClassName("btn"); // HTMLCollection(10): array-like object
Array.from(buttons).forEach(button => {
button.addEventListener("click", () => console.log("클릭"))
});
- css의 last-child 속성
* 주의: 부모 요소에 넣어서 자식 요소 선택하는 게 아니다!
/* Selects **any <div>** that is the last element
among its **siblings** */
div:last-child {
margin-bottom: 2rem;
}
- css vertical-align 속성
- inline 또는 table-cell box에서의 수직 정렬을 지정
- 블록 요소의 종류
- dt, dd, ul, li, ol, dl, div, p, h1, h2, h3, h4, h5, h6
- 인라인 요소의 종류
- a, img, span, srong, input, textarea, select
즉, li는 블록 요소! li 안 텍스트를 vertical 정렬하기 위해서 → padding을 주던지, flex로 바꾸던지.. 혹은, 부모에 display: table; li에 display: table-cell; vertical-align: middle;
- margin-left: auto;(맨 오른쪽 정렬) margin: 0 auto; (가운데 정렬) 적용 안 됨
https://15it.tistory.com/entry/가운데-정렬을-시키는-margin-0-auto-명령어가-적용이-안될때-확인해야하는-부분
- width가 정확해야 한다.
- inline 속성 태그에 선언하면 적용이 안 된다.
- button tag는 inline 속성 태그이다. 따라서, display: block으로 설정해야 적용된다.
references
- CORS Error 해결
- 브라우저에서 기본적으로 API를 요청 시 → 브라우저의 현재 주소와 API 의 주소의 도메인이 일치해야 데이터를 접근 할 수 있게 되어 있다.
- 다른 도메인에서 API를 요청할 경우, CORS 에러가 난다.(브라우저의 CORS 정책에 위반) 따라서, CORS 설정이 필요!
CORS란?
- 다른 도메인에 리소스를 요청할 경우 서로 다른 origin에 대하여 HTTP 요청을 가능하게 해주는 표준이다.
- 웹브라우저에서 외부 도메인 서버와 통신하기 위한 방식을 표준화한 스팩
- 서버와 클라이언트가 정해진 헤더를 통해 서로 요청이나 응답에 반응할지 결정하는 방식 * SOP(Same-Origin Policy): 동일 출처(도메인)의 리소스만 요청이 가능하다. * Origin은 프로토콜, 주소, 포트번호의 쌍([프로토콜]://[Host의 IP 주소나 URL]:[포트번호])
CORS 에러 대응 방법 1)
Access-Control-Allow-Origin
- 서버 측에서 Access-Control-Allow-Origin 헤더에 접근 권한 설정→ “*“를 설정 시 모든 외부 출처에서 접속을 할 수 있게 된다. → 보안 문제 → “Access-Control-Allow-Origin: http://localhost:3000”으로 헤더 적용
CORS 에러 대응 방법 2)
- Proxy 설정 → 백엔드에서 개발서버를 위한 CORS 설정을 안해도 된다.
- 외부 도메인 서버를 통하지 않고 자신의 서버를 매개로 하여 외부 서버에 요청 → Proxy Server라는 출처를 통하기 때문에 CORS 정책을 위반하지 않게 된다.
- ⇒ Webpack에서 간단하게 Proxy 서버 기능 지원
- 웹팩 개발서버의 프록시를 사용 → API를 요청 할 때 백엔드 서버에 직접적으로 요청을 하지 않고, 현재 개발서버의 주소로 요청 → 웹팩 개발 서버에서 해당 요청을 받아 그대로 백엔드 서버로 전달하고, 백엔드 서버에서 응답한 내용을 다시 브라우저쪽으로 반환
CRA 를 통해 만든 리액트 프로젝트에서는 proxy 설정을 쉽게 할 수 있다.
// package.json { ... "proxy": "http://groupby.biz" }
references
- https://ryulog.tistory.com/138
- https://devport.tistory.com/13
- https://react.vlpt.us/redux-middleware/09-cors-and-proxy.html
* Proxy 서버란?
- 클라이언트가 자신을 거쳐 다른 네트워크에 접속할 수 있도록 중간에서 대리해주는 서버
- 클라이언트 → 프록시 서버로 데이터 전송, 프록시 서버 → 웹 서버로 웹 요청
웹 서버 → 프록시 서버로 웹 응답 → 프록시 서버에서 클라이언트로 데이터 전송 사용 목적
- 캐시 데이터 사용
- 프록시 서버에 요청된 내용을 캐시에 저장 → 해당 내용을 재요청 시 서버에 따로 접속하지 않고 캐시에 저장된 내용을 그대로 돌려줌 → 시간 절약, 외부 트래픽을 줄임, 네트워크 병목 현상 방지!
- 보안 목적
- 프록시 서버가 중간에 끼면 IP를 숨기는 것이 가능해진다. 또한, 프록시 서버를 방화벽으로 사용하기도 함(프록시 방화벽)
- 접속 우회
- 프록시 서버를 사용하여 접속을 다른나라로 우회.
references
- put, patch method
- HTTP Method는 크게 GET, POST, PUT, DELETE가 있으며, CRUD에서 보통 조회는 GET, 등록은 POST, 수정은 PUT, 삭제는 DELETE를 이용한다.
- PATCH와 PUT은 둘 다 데이터의 수정을 위한 method
- PUT 요청 → 요청을 일부분만 보낸 경우 나머지는 default 값으로 수정되므로(전달한 필드외 모두 null 혹은 default 값처리) 바뀌지 않는 부분도 모두 보내야 한다. → 전체적인 수정이 필요할 때 사용
- PATCH 요청 → 요청의 일부분만 보내면 새롭게 바뀐 부분만 반영, 나머지는 기존 데이터가 유지된다. → 리소스의 일부만 수정할 때 사용
references
- https://devuna.tistory.com/77
- withCredentials option
- 같은 origin에서 http 통신을 하는 경우 알아서 cookie가 request header에 들어가게 되지만, 그렇지 않은 경우에는 직접 설정을 해주어야 request header에 쿠기가 자동으로 들어간다.
설정 방법
프론트 → withCredentials : true
서버 → Access-Control-Allow-Credentials : true
- 요청 시에 위와 같이 프론트, 서버 둘 다 설정을 해 주면 해결.