HTML method
가 될 수도 있고 URL
이 될 수도 있다.request
는 한 번에 오지 않는다. Buffer
의 단위로 날아온다. 그래서 그 Buffer 를 받아 누적시키고, 그리고 그것을 toString()
을 통해 사람이 읽을 수 있는 문자열로 바꿔주는 과정을 거쳐야 한다. express.js
에서는 이것을 body-parser
를 통해 간단하게 처리할 수 있지만, node.js 만을 가지고 서버를 작성한다면 위와 같은 과정을 꼭 거쳐야 한다.pre-flight request
와 OPTIONS
method 는 header
를 통해서 내가 CORS
허용한 client 가 맞는지를 검사해준다. 그래서 OPTIONS
method 또한 routing 으로 처리를 꼭 해줘야 한다.SIMPLE REQUEST
의 경우는 OPTIONS 를 통한 검증이 없이도 바로 소통이 가능하다.module.exports
vs exports
의 비교exports
는 module.exports
를 참조한다. module.exports
에 이미 어떤 값을 할당한 상황에 exports
에 별도의 값을 할당하면, 완전히 새로운 값이 할당된다.express
와 그 부분들cors
미들웨어를 사용하면, app.options()
등을 통해 routing 하지 않아도 잘 된다.next()
를 사용하고 안 하고의 차이는, 직접 해 보면서 알아보자!React 의 Flow 와 특성에 대해 잘 이해하자
React
가 등장하였음component
하나의 의미를 가진 독립적인 단위 모듈. 소위 말해 "나만의 HTML 코드" 라고 생각하면 편하다.
우리는 일반적으로 HTML 코드를 이런 식으로 구현한다.
<div class="tweet">
<span class="userId"> @walli </span>
<div class="contents"> hello, my name is walli! </div>
<div class="time"> 43 seconds ago</div>
</div>
이는 정석적인 태그이지만, 저것들을 계속해서 만들어주기는 귀찮은 일이다.
그렇다면, 저 tweet
이라는 class
를 구현하는 총체적인 과정을 하나의 함수로, 그 안에 들어가는 필요한 부분들을 함수의 인자로 간주하여 하나의 form 을 만든다면, 어떨까?
<Tweet userId="walli" time"43">
hello, my name is walli!
</Tweet>
이 코드가 위와 같은 동작을 한다면, 위와 같은 코드를 여러 번 생산해야 하는 경우 더욱 편리해진다. 즉, 재사용성이 증가하는 것이다. 그리고, 훨씬 더 직관적이다. Tweet 이라는 form 에 arguments 들을 집어넣어 Tweet 을 만들어주는구나! 라고 조금 더 쉽게 알 수 있다.
두 번째의 코드가 바로 React 의 Component
개념이다.
ES6
React
는 ES6
문법에 기반한 프론트엔드 라이브러리로, ES6 문법에 대한 숙지가 필수적이다. 특히 리액트를 사용하면서 꼭 알아야 할 ES6 문법은 다음과 같다.
JSX
자바스크립트의 확장 문법으로, 우리가 작성한 React Component 를 화면에 보여주기 위해 사용한다. React Component 에서는 반드시 JSX
를 return 해 주어야 한다.
class Hello extends Component {
render() {
return (
<div>
<h1>Hello world!</h1>
<div>
)
}
}
하나의 Component 를 만들어보았다. 저기서 render()
라는 메서드에 return 되는 값에 주목해보자.
<div>
<h1>Hello world!</h1>
<div>
이렇게 React 에서, JS와 함께 쓰이는 이런 HTML 태그들을 JSX
라고 한다.
물론 JSX 없이도 Component 를 만들 순 있다.
React.createElements('header', {className: 'App-Container'} ... );
그렇지만 JSX 를 사용하는 것에 비해 가독성이 떨어지기에, JSX 를 활용하는 것이 조금 더 현명한 선택이라고 할 수 있다.
<header className='App-container'> ... </header>
JSX
로 아까전의 것을 구현해 본다면 이런 식으로 구현이 가능할 것이다. 복잡도는 떨어지고, 가독성은 올라갔다.
이 JSX 를 통해 작성한 코드는 babel
이라는 트랜스컴파일러가 자동으로 위와 같은 코드로 변환해준다.
JSX 는 자바스크립트 코드로 변환되기 때문에, 지켜야 하는 규칙 몇 가지가 존재한다.
<div>
<h1>hello</h1>
<div>
<div>
<h1>world</h1>
<div>
위와 같은 코드는 두 개의 element 로 나뉘어져 있는 상황이다. JSX 는 이들을 하나의 엘리먼트로 감싸야 한다.
<div>
<div>
<h1>hello</h1>
<div>
<div>
<h1>hello</h1>
<div>
</div>
{ }
안에 작성해야 한다class App extends Component {
render() {
const name = "walli";
return (
<div>
hello! ${name}
<div>
)
}
}
name 이라는 변수가 보다시피 { }
안에서 사용되는 모습을 볼 수 있다.
IIFE
혹은 삼항 연산자를 사용해야 한다.<div>
{
(1+1===2)? (<h1>정답</h1>) : (<h1>탈락</h1>)
}
</div>
className
을 사용한다.<div class='App-Container'>hello</div> // class 를 사용해서 불가능
<div className='App-Container'>hello</div> // JSX 문법에 맞춰 className 을 사용
그 이유는 ES6 문법 중에 class
키워드가 있어서 겹치기 때문에 겹치지 않게 하기 위해서이다.
리액트는 단방향 데이터 흐름 방식이다. 즉, 데이터가 한 방향으로만 이동한다는 것이다. 위에서 아래로 떨어지는 Top-Down 방식. 아래에서 위로 거꾸로 올라가는 것은 불가능하다.
class Parent extends Component {
render() {
return (
<Child />
)
}
}
이것처럼, 부모 Component 에서 자식 Component 로 데이터를 내려줄 순 있다. 그리고 아까 말했듯이, 그 직접적인 역은 불가능하다.
그러나, "간접적인" 방법을 통해서는 아래에서(자식 Component에서) 위로(부모 Component로) 데이터를 전달해 줄 수 있다.
상위 Component 에서 하위 Component 로 오가는 일련의 데이터들을 총칭해 일컫는 말이다. 하위 Component 는 해당 props 를 단순히 사용만 가능 하며, 변경할 수 없다.
//Parent 라는 상위 Component 에서 Child라는 하위 Component 로 Props 를 내려주는 과정
//여기서의 props 는 "name" 이 된다
function Parent() {
return(
<Child name="walli" />
)
}
//Parent 에서 받은 props 를 Child 가 받는 과정
//하위 Component 가 props 에 접근하기 위해선 Component 의 인자로 props 를 명시해 줘야 하며,
//그 Props 를 JSX 문법으로 사용하기 위해선 상위에서 내려준 이름을 그대로 사용해야 한다
function Child(props) {
return (
<h1>hello, {props.name}</h1>
)
}
component 가 갖는 상태, 객체의 형태로 component 내에서 보관하고, 관리한다. 이 state 를 사용하기 위해서 component 는 class
를 통해 작성이 되어야 하며, 값을 변경할 때는 반드시 setState
메서드를 이용해야 한다.
class Person extends Component {
state = {
power: 50,
isHungry: false
}
render() {
return (
//...JSX code
)
}
}
state
를 사용하기 위해서는 위의 코드처럼 class component
를 만들어주고, 그 안에 state
라는 객체를 만든 뒤, 객체 안에다가 상태들을 정의하고, 값을 할당하면 된다.
class Person extends Component {
state = {
power: 50,
isHungry: false
}
//이런 식으로 state 를 직접 바꿔주는 것은 안 된다.
chanegeState() {
this.state.power = 100;
}
render() {
return (
//...JSX code
)
}
}
class Person extends Component {
state = {
power: 50,
isHungry: false
}
//이렇게 setState 를 이용해서 바꿔주어야 한다.
chanegeState() {
this.setState({
power: 100;
})
render() {
return (
//...JSX code
)
}
}
값을 바꾸어 줄 때도 위의 코드처럼 this.state.power = 100
과 같이 직접 할당, 직접 접근을 해서는 안 되며, this.setState({ power: 100 })
와 같이 setState
메서드를 사용해주어야 한다.
이렇게 setState
메서드를 통해 state 의 값을 바꾸면 render()
함수가 다시 실행된다.
React 는
라는 각 단계의 전/후로 특정 메서드가 호출된다. 자세한 내용은 React 의 Life Cycle 문서를 확인하면 알 수 있다.
React 의 Life Cycle 문서 :
Component 생성 시의 Life Cycle
Constructor
) 가 호출됨render()
메서드가 실행됨 → JSX
를 반환하여 화면에 그려주는 작업이 일어남componentDidMount()
라는 메서드가 호출됨Component 업데이트 시의 Life Cycle
state
의 값이 변경될 때 Component 가 업데이트 됨render()
메서드가 실행되며 위와 같이 업데이트 된 값이 화면에 나타남componentDidUpdate()
라는 메서드가 실행됨우리는 이 메서드들을 적절히 이용하여 원하는 타이밍에 원하는 작업들을 수행할 수 있다. 그렇기에 이 Life Cycle Method 는 꼭 이해해야 하며, 해당 Life Cycle Method 들을 이용하기 위해선 Class Component
로 component 를 작성해야 한다. 왜냐면, state
를 사용하기 위해선 Class Component
가 필요하기 때문이다.