우아한 테크러닝 DAY 4

3 minute read

컴포넌트 디자인

상위에 성격이 다른 건 분리하며 크기를 쪼개자
어떻게 쪼갤까?? -> 쪼개야겠다.. 싶을때 ㅋㅋㅋ
변수 안에 변하는게 상태
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();