<비동기 , 동기 학습영상>

 

 

 

동기식은 코드가 짜여진 순서대로 실행된다(1번 함수 실행&결과-> 2번 함수(시간오래걸림) 실행&결과 -> 3번 함수 실행&결과)

 

비동기식은 코드가 짜여진 순서대로 실행되지 않는다.

 

(1번 함수 실행&결과 -> 2번 비동기 함수 Task queue에 호출됨 -> 3번 함수 실행&결과 -> 2번 실행&결과)

/일반적인 경우 ex)setTimeout()

 

(1번 함수 실행&결과 -> 2번 비동기 함수 실행 + Task queue에 호출됨 -> 3번 함수 실행&결과 -> 2번 함수 실행&결과)

  /통신할 때(ex 데이터 불러올 때)  처음 2번 함수가 실행 될 때는 데이터를 호출하는 것이 실행되는 것이고 두번째 실행은 데이터를 호출

한 후의 다음 로직을 실행하는 것이다. 그다음 일반적인 경우처럼 결과를 내놓는다.

 

 

동기식 같은 경우에는 실행하는데 시간이 오래걸리는 함수(2번 함수)라도 기다렸다가 절차적으로 순서대로 실행한다.

비동기식 같은 경우는 기다리지 않고 바로 다음 함수인 3번 함수를 실행한다. 그리고 나중에 2번 함수가 실행된다.

 

왜 굳이 비동기식을 사용하는걸까? 만약 동기식처럼 2번 함수가 실행될 때까지 기다렸다가 실행되어서야 3번 함수를 실행한다면

2번 함수가 실행되는 동안 아무것도 할 수 없게되니 효율성이 급감한다. 

 

 


 

 

 

React의 setState함수는 비동기식 함수이다.

<예제>

import React from 'react';
import './App.css';

class App extends Recat.Component {
  constructor(props){
    super(props);
    this.state = {
     number: 0
    }
    this.handleClick = this.handleClick.bind(this);
  }
  
  handleClick(){
    this.setState({
      number: this.state.number + 1
    });
  }
  
  render(){
    return(
      <div className="App">
        <h1>Hello Wecode!</h1>
        <h2>Current Number: {this.state.number}</h2>
        <button onClick={this.handleClick} type="button" className="btn">
          더하기
        </button>
      </div>
    );
  }
}

 

 

더하기 버튼을 누르면 Current Number가 1씩 올라가는 컴포넌트다.

 

 

  handleClick(){
    this.setState({
      number: this.state.number + 1
    });
    
    console.log(this.state.number)
  }

 

handleClick함수 안

비동기식 함수 setState밑에 console.log를 찍으면 어떻게 될까?

 

 

 

더하기 버튼을 누름.

Current Number: 1       console.log: 0

Current Number: 2       console.log: 1

Current Number: 3       console.log: 2

 

console.log는 숫자가 하나씩 밀려서 나타나게 된다.

 

 

그 이유는 handleClick함수 안의 setState가 비동기식 함수여서 아직 +1한 값이 this.state.number에 반영되지 않았는데

바로 다음 줄인 console.log가 실행돼서 더한 값이 반영되지 않은 this.state.number를 찍었기 때문이다.

 

handleClick함수를 호출했을 때 다음과 같은 과정으로 진행된다.

 

handleClick호출 -> setState는 Task queue에 호출됨 -> console.log실행&결과 -> setState실행&결과
->render업데이트 반영

만약에 handleLogClick이라는 함수가 있다고 가정해보자.

handleLogClick = () => {
  console.log(this.state.number)
}

handleClick을 호출 후  handleLogClick을 호출하면 다음과 같은 순서로 진행된다.

handleClick호출 -> setState는 Task queue에 호출됨-> console.log실행&결과 -> setState실행&결과
->render업데이트 반영 -> handleLogClick호출

즉, handleClick이라는 이벤트가 완전히 끝날 때까지 handLogClick은 시작되지 않는다! 
그래서 handLogClick은 최신값을 가지게 되는 것이다.

 

 

반면에 Current Number옆의 {this.state.number}는 handleClick함수가 끝난 후에 render에서 쓰인 것이기 때문에 최신상태로

반영된 것이다.

 

 

 

 

그렇다면 handleClick함수 안에서 어떻게 바로 최신으로 반영된 this.state.number를 볼 수 있을까?

 

방법은 두 가지가 있다.

 

방법1)

  handleClick(){
    this.setState({
      number: this.state.number + 1,
      () => {console.log(this.state.number}
    });
  }

 

setState에 콜백함수로 console.log(this.state.number)를 넘겨주면 된다. 

 

이렇게 하면 number: this.state.number + 1이 끝난 다음(즉, 비동기로 주어진 일을 다 마친 다음) 이 함수를 실행하도록 

추후 업무를 맡겨놓는 것이다.

 

 이걸 콜백함수(callback function)라고 한다.

 

 

 

방법2)

  handleChange(e){
    this.setState({
      text: e.target.value
    });
    
    console.log(e.target.value)
  }

 

button태그 대신

input태그가 있는 경우 onChange이벤트로 this.state.text에 변하는 값을 실시간으로 저장한다고 했을 때

 

제대로 반영되는지 console.log를 찍어 확인하려고 한다면 콜백함수를 사용할 수도 있겠지만

그 대신 setState밖에서 console.log에 e.target.value를 넣으면 값이 제대로 들어가는지 확인 할 수 있다.

 

 

 

 


 

 

같이 읽어보면 좋을 자료

 

setState 를 함수형으로 사용하기

리액트를 사용할 때 상태관리를 어떻게 해야할까? 그런데 상태 관리를 고민하기 이전에 무엇이 상태(state)고 어떤 것이 프로퍼티(props)가 되어야하는 것일까? 그리고 setState 어떻게 동작하는 것일

dodokim.medium.com

 

밑의 내용은 위의 참고자료를 읽는데 도움 되는 내용이다.

 

 

 

reconciliation(재조정)이라는 뜻

 

 

배칭이란? (What is batching?)

배칭은 React가 더 나은 성능을 위해 여러 개의 state 업데이트를 하나의 리렌더링 (re-render)로 묶는 것을 의미한다.

예를들어, 하나의 클릭 이벤트 안에 두 개의 state 업데이트를 가지고 있다면, React는 언제나 이 작업을 배칭하여 하나의 리렌더링으로 만들었다. 다음과 같은 코드를 실행해보면, 매 번 누를 때마다, state를 두 번 변경하였지만, React가 단 한 번의 렌더링만 수행한 것을 볼 수 있다.

 

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    setCount((c) => c + 1); // 아직 리렌더링 하지 않는다
    setFlag((f) => !f); // 아직 리렌더링 하지 않는다
    // React는 이 함수가 끝나면 리렌더링을 한다 (이것이 배칭이다!)
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style=>{count}</h1>
    </div>
  );
}

<출처:https://immigration9.github.io/react/2021/06/12/automatic-batching-react.html>

 

 

'React > Today I learned' 카테고리의 다른 글

Sass  (0) 2021.06.30
Router  (0) 2021.06.29
[React] why react?, JSX, Node.js, CRA  (0) 2021.06.27
[React] key값을 써야하는 이유  (0) 2021.06.26
Class 컴포넌트 Constructor에서 super(props)를 써야하는 이유  (0) 2021.06.23

+ Recent posts