JS는 외부데이터를 비동기로 가져온다. 이유는 서버와 통신하는 동안 클라이언트가 멈춰서는 안 되기 때문이다. 특히 JS는 싱글스레드이기 때문에 해당 문제는 더더욱 중요하다(공장의 컨베이어 벨트가 딱 하나밖에 없다고 생각하면 된다)
비동기를 처리하는 가장 무난한 방법
Promise
fetch API
와 then()
을 사용해서 하는 방법은 이 Promise
를 이용하는 방법임
async & await
Promise
의 syntactic sugar, 코드의 가독성을 올려주는 방식이니 적극 활용할 수 있도록 하자
setTimeout()
과 callback
을 활용한 비동기함수로부터 데이터 받아오기function hello (callback) {
setTimeout(() => {
var hello = "hi";
var name = "my name is";
var th = "IM22";
callback(hello + ' ' + name + ' ' + th)
}, 2000);
}
hello((value) => {
console.log(value)
});
해당 코드의 원리는 함수안의 callback
에 어떤 값을 넘겨, 그 넘겨받은 값을 활용하는 방식이다.
React
에서 데이터를 언제, 어떻게 불러와야 할까?componentDidMount
에서 불러와야 한다.
props
부모 컴포넌트에서 하위 컴포넌트로 내려주는 데이터. 수정이 불가능하다(읽기전용).
state
컴포넌트가 가지는 상태. state
를 변경할 때는 반드시 setState()
를 사용해서 값을 변경해주어야 한다.
Life Cycle
컴포넌트가 생성될 때, 업데이트 될 때, 사라질 때, 각 단계의 전후로 특정 메서드가 호출되는 현상
리액트는 컴포넌트 단위로 생각하고 설계해야 한다. 왜냐하면 React
자체가 컴포넌트의 상호작용으로 이뤄지는 프레임워크이기 때문이다.
keys
in React여러개의 컴포넌트를 렌더링 할 때, props
에 문자열 값으로 구분할 만한 무언가를 넘겨준다.
state
를 가질 수 있느냐, 없느냐의 차이가 있다. 전자는 가질 수 없고, 후자는 가질 수 있다. 전자는 추가로 Life Cycle method
를 사용할 수도 없다. (후자는 가능하다)
setState()
를 사용하여 state
를 바꾸어줘야하는 이유setState()
를 통해 해당 작업을 진행하지 않으면, Life Cycle
에 연동되지 않아서 componentDidUpdate
가 실행되지 않아 렌더링이 다시 진행되지 않는다.
props
?부모 컴포넌트에서 자식 컴포넌트로 흐르는 데이터.
state
to parent component?setState
를 실행하는 함수를 props
에 담아서 내려보내면 된다. 그러나, this
를 잘 고려해야 한다. 클래스 컴포넌트의 constructor
에서부터 this binding
을 통해 메서드를 잘 묶어주어야 한다.
bind
를 해 주어야 하는가?그 이유는 우리가 클래스 컴포넌트에서 만든 메서드들이 정확히 그 클래스 컴포넌트 스코프를 참고하지 않기 때문이다.
import React from "react";
import "./styles.css";
export default class App extends React.Component {
this.state = {
name: "김코딩"
};
handleClick(e) {
console.log(this)
this.setState({ name: "박해커" });
}
render() {
return (
<div>
<button onClick={this.handleClick.bind(this)}>버튼</button>
</div>
);
}
}
이런 리액트 코드를 실행했을 때, console.log(this)
를 해서 this
를 찍으면 window
가 나온다. 지금은 props
를 내려주는 과정에서 bind
를 해 주었지만, 정석적인 방법은 constructor
안에서 바로 사용하는 것.
import React from "react";
import "./styles.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "김코딩"
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
console.log(this)
this.setState({ name: "박해커" });
}
render() {
return (
<div>
<button onClick={this.handleClick}>버튼</button>
</div>
);
}
}
이런 식으로. 공식문서에 "권장" 하는 constructor
방식을 통해 사용하는 것이 좋다.
그리고 arrow function
으로 바인딩을 걸어주는 건, 공식문서에서 본 것처럼 당연히 비추천이다. 매번 새로운 props
가 내려가 더 많은 렌더링이 진행되기 때문이다.
componentDidMount
와 같이 실행해주면 된다.fsevents is not a constructor” react error
왜 이런 것이 뜬 건지 구글링을 해 봐서 stackoverflow 링크의 답변을 하나 찾게 되었다.
참고문서 : How to fix "TypeError: fsevents is not a constructor" react error
나와 같은 문제를 겪고 있는 사람이었고, 리액트 문제인거도 똑같았다. 베스트 답변은 npm audit fix --force
를 해보라는 이야기였는데, 다행히 한 번에 해결되었다.
key
를 사용하는 걸까?"자식에 대한 재귀적 처리" 항목에서 답을 찾을 수 있었다. React 는 기본적으로 DOM 노드의 자식들을 재귀적으로 처리할 때 기본적으로 동시에 두 리스트를 순회하고 차이점이 있는 경우 변경을 생성한다. 이 특성을 고려하였을 때 key
라는 props
를 추가해주면 React 는 기존 트리와 이후 트리의 자식들이 일치하는지 확인하기 더 편하다.
배열의 인덱스는 최후의 수단이다. 항목들이 재배열되어 인덱스가 꼬여버리면 state
단에서 문제가 생기기 때문에 index
는 가급적 이용하지 말고 각각을 명확하게 구분짓는 무언가를 사용하자.
참고문서 : 재조정 (Reconciliation) - React
Line 10 exceeds the maximum line length of 120
React 는 한 줄에 글자가 120개를 넘을 수 없다. 그래서 적절한 개행(enter)으로 갯수제한조건을 맞춰주어야 한다.
||
React 에서 props null check 는 불가능하다, 물론 default parameter
를 사용하는 것이 가능하긴 props
에서는 불가능하다. 왜냐면 props 는 읽기 전용이기 때문에 다른 값을 할당해 줄 수 없기 때문이다.
그래서 페어분에게 새로운(나한테만 새로운...) 방법을 배웠다. 바로 ||
연산자를 활용한 null check 이다.
function a(a, b) {
b || 1
return a + b;
}
a(10) // 11
이렇게 하게 된다면 11이 나오게 된다. 그 이유는 a
라는 함수를 호출했는데 b
라는 인자가 존재하지 않는, 그러니까 falsy 한 값이기 때문이다. 그래서 b
는 falsy 하기 때문에 1이 대신 b의 인자로 들어가게 되고, 그래서 11이 나오게 되었다.
React 코드를 보자
render() {
return (
<div>
<Nav />
<div className="col-md-7">
<VideoPlayer video={this.state.currentVideo || fakeData[0]}/>
</div>
<div className="col-md-5">
<VideoList videos={this.state.videos || fakeData} event={this.videoClick}/>
</div>
</div>
)}
}
저기 나와있는 것처럼 {this.state.currentVideo || fakeData[0]}
에 이를 응용했다. currentVideo
가 falsy 한 값이면, fakeData[0]
를 할당해주는 식이었다.
fetch API
에서의 생략fetch(url).then(res => res.json())
.then(data => callback(data))
.then(Data=>callback(data))
같은 상황에서 마지막 인자가 함수 안에 바로 들어가는 인자와 "완전히 똑같다면", 해당 경우에는 arrow function
을 생략해도 된다
fetch(url).then(res => res.json())
.then(data => callback(data))
.then(callback)
fetch is not a function
이유를 모르겠다. 레퍼런스 코드를 보고 고쳐봐야 할 듯 하다. MDN 문서를 보아도 딱히 걸릴만한 것들이 없는데 이유가 뭘까. fetch
에 오탈자가 있는 것도 아니고, wrong Object
관련 문제도 아니고, 이미 존재하는 property
를 공유한 것도 아니고, import/export
도 잘 해주었는데. 감이 오질 않는다.
참고문서 : TypeError: "x" is not a function
오늘 페어분이 정말정말정말로 능숙하게 코드진행을 착착착 하셔서 마지막에 용기를 내어 어떻게 공부하시냐고 물어보았다. 아주 많은 걸 얻을 수 있었고, 정말 대단하다는 생각이 들었다. 페어프로그래밍을 하면서 배워가기만 하는 입장이라 부끄럽다. 더 잘 해야지.