우아한 테크러닝 DAY 4
컴포넌트 디자인
상위에 성격이 다른 건 분리하며 크기를 쪼개자
어떻게 쪼갤까?? -> 쪼개야겠다.. 싶을때 ㅋㅋㅋ
변수 안에 변하는게 상태
index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
const sessionList = [
{ id: 1, title: "1회차: Overview" },
{ id: 2, title: "2회차: Redux 만들기" },
{ id: 3, title: "3회차: React 만들기" },
{ id: 4, title: "4회차: 컴포넌트 디자인 및 비동기" }
];
ReactDOM.render(
<React.StrictMode>
<App store= />
</React.StrictMode>,
rootElement
);
App.js
단계 1
const App = (props) => {
return (
<div>
<header>
<h1>React and TypeScript</h1>
</header>
<p>전체 세션 갯수 : 4개</p>
<button onClick={onToggleDisplayOrder}>재정렬</button>
<ul>
<li>1회차: Overview</li>
<li>2회차: Redux 만들기</li>
<li>3회차: React 만들기</li>
<li>4회차: 컴포넌트 디자인 및 비동기</li>
</ul>
</div>
);
};
단계 2
const App = (props) => {
return (
<div>
<header>
<h1>React and TypeScript</h1>
</header>
<p>전체 세션 갯수 : 4개</p>
<button onClick={onToggleDisplayOrder}>재정렬</button>
<ul>
{sessionList.map((session) => (
<li>{session.title}</li>
))}
</ul>
</div>
);
};
단계 3 ; 클래스 컴포넌트
이제는 없어질 것 같은게 클래스 컴포넌트
클래스 컴포넌트나 함수형 컴포넌트나 다 되지만 함수형이 상태관리에 더 간단하니까!
const SessionItem = ({ title }) => <li>{title}</li>;
class ClassApp extends React.Component { //상태가 여러 메소드에 분산되어 저장
//실행컨텍스트, 프로토타입,,,
constructor(props){
super(props); //this porps에 넣어주는 역할
//this.onToggleDisplayOrder = this.onToggleDisplayOrder.bind(this); //초창기는 이렇게 THIS 전달
this.state = {
displayOrder: "ASC" //클릭해서 상태가 바뀌면 감지해서 바꾸어야하는데 그걸 감지 못해서
}
}
onToggleDisplayOrder() {
//event handler
this.setState({ //이때 this는 다른 this가 된다
displayOrder: displayOrder === "ASC" ? "DESC" : "ASC"
});
}
toggleDisplayOrder = () => {
this.setState({ //arrow function을 사용하면 binding 불필요해진다
displayOrder: displayOrder === "ASC" ? "DESC" : "ASC"
});
}
render(){
return(
<div>
여기
<button onClick={this.toggleDisplayOrder}>정렬</button>
</div>
)
}
}
결과적으로 함수형 컴포넌트
함수 하나에 응집되어 상태 관리
정렬하는 상태 만들기 ; 상태는 어떻게 만들까
함수는 상태를 가질 수 없다 -> orderedSessionList로 해결!
함수 안에서 hook이 클로저가 되는 것이지 hook 자체가 클로저는 아님!
import React from "react";
const SessionItem = ({ title }) => <li>{title}</li>;
const App = (props) => {
const [displayOrder, toggleDisplayOrder] = React.useState("ASC");
const { sessionList } = props.store;
const orderedSessionList = sessionList.map((session, i) => ({
...session,
order: i
}));
//console.log(sessionList, orderedSessionList);
const onToggleDisplayOrder = () => {
toggleDisplayOrder(displayOrder === "ASC" ? "DESC" : "ASC");
};
return (
<div>
<header>
<h1>React and TypeScript</h1>
</header>
<p>전체 세션 갯수 : 4개</p>
<button onClick={onToggleDisplayOrder}>재정렬</button>
<ul>
{orderedSessionList.map((session) => (
<SessionItem title={session.title} />
))}
</ul>
</div>
);
};
export default App;
javascript의 3가지 비동기 보기
x로 dependency가 걸려있어서 x가 확정되기 전에 계산될 수 없다
변수적인 dependency!
const x = 10;
const y = x * 10;
이거는 함수니까 x값이 확정되는 순간을 아랫줄로 지연시킨 것 얘도 안된다
LAZY : 지연호출!
const x = () => 10;
const y = x() * 10;
Promise
promise함수는 거의 비동기 Promise();
const p = new Promise(function(resolve, reject){ //이거는 resolve, reject 두 함수 전달하기 위해 호출하는 것
setTimeout(()=>{
resolve("1"); //얘는 함수에 잡혀서 지연호출 된 것!
}, 1000)
});
p.then(function (r){
console.log(r);
});
Generator
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Generator
함수 이름 앞에 * 붙은게 generator 함수
코루틴(C#)이라고 하는 함수의 구현체
함수: 입력 -> 계산 -> 반환
함순데 호출자한테 리턴을 여러번 할 수 있게 하면 어떨까 ?
호출되면 마지막 실행했던 데서 다시 시작하도록
done이라는 flag로 t/f 주는데 true면 또 다음으로 갈 수 있다
function* make(){
return 1;
}
const i = make();
console.log(i); //1이 들어오지 않고 generator 객체를 전달
function* makeNumbr(){
let num = 1;
while(true){
yield num++; //generator의 return ; 함수를 끝내지 않는다.
//yield는 값을 주고 다시 돌아오겠다고 함
}
}
const i = makeNumber();
console.log(i.next());
function* makeNumber(){
let num = 1; //내부의 상태를 계속 유지하고 있다.
while(true){
const x = yield num++;
console.log(x);
}
}
콜백을 사용하지 않고 동기 구조처럼 사용하는 것 (saga)
const delay = ms => new Promise((resolve)=> setTimeout(resolve, ms));
function* main(){
console.log("시작");
yield delay(3000);
console.log('3초 뒤'); //동기 코드처럼 보인다
//밖에서 함수를 제어하고, 함수 내에선 동기적으로 되는듯한 코드를 쓰게 한다.
}
const it = main();
const {value} = it.next(); //value에는 promise객체가 온다
if (value instanceof Promise){
value.then(()=>{ //객체니까 then이 가능
it.next();
});
}
콜백 구조
const delay = ms => new Promise((resolve)=> setTimeout(resolve, ms));
delay(3000).then(()=>{
console.log('3초 뒤'); //콜백 함수 구조
})
Async
async 붙은게 비동기 함수
await는 promise에 최적화되어 있어서 promise일 때만 쓸 수 있고
yield는 사용될 수 있는 범위가 훨씬 넓다
const delay = ms => new Promise((resolve)=> setTimeout(resolve, ms));
async function main2(){
console.log("시작");
await delay(3000);
console.log("3초 뒤입니다.");
}
main2();