본문 바로가기

CodeTech/React

React - 7 data-fetch [setTimeout, async/await]

컴포넌트가 실행될때 constructor -> render() -> componentDidMount() 이렇게 실행된다.

그렇다면 6초후에 상태를 변경하고 싶다면?

 

class App extends React.Component {
  state = {
    isLoading: true
  };
  // render하면 진행되는 함수이다. 이함수는 setTimeout()함수를 통해 setState()를 6초 후에 시켰다.
  // 즉 data를 fetch 한것이다.
  componentDidMount() {
    setTimeout(() => {
      this.setState({ isLoading: false });
    }, 6000)
  }
  render() {
    const { isLoading } = this.state;
    return (
      <div>{isLoading ? "Loading..." : "We are ready"}</div>
    );
  }
}

위코드를 보면 isLoading이 true이면 "Loading반환, false이면 We are ready라는 코드를 반환하고

componentDidMount()함수안에 setTimeout()이라는 함수를 만들어서 isLoading 상태를  6초 뒤에 false로 만들었다.

즉, componentDidMount()안에서 data를 fetch 한것이다.

 

JS에서 data fetch를 하는 방법은 fetch()를 써야하지만 더 좋은게 있다.

 

Axios

- 기본적으로 axios는 fetch위에 있는 레이어이다. 

 

동기식  vs 비동기식 

- 함수를 실행할때 시간이 걸리게되면 컴퓨터는 우선순위를 판단해서 다른 것부터 실행한다.

하지만 이렇게되면 본래 코드가 실행되는 우선순위가 밀려 개발자가 원하는대로 작동이 안되게 되는데

이를 막고자 하는 것이 비동기식 이다.

 

동기식 : 여러 프로세스의 처리가 동시에 시작해서 동시에 끝나게되어 결과물이 한꺼번에 나온다.

- 하지만 그동안 아무것도 처리되지 않는다.

 

비동기식 : 여러 프로세스를 순차적으로 처리함으로서 의도적으로 다른프로그램 시작시간과 끝나는 시간을 조절해서

동기식 보다 복잡하더라도 그 끝날 때 까지 기다리는 시간 동안 아얘 다른 작업을 처리 할수 있다.

- 자원의 효율적 관리 

 

동기식으로 구현하면 함수가 끝날때까지 기다렸다가 다음으로 넘어간다.

 

하지만 동기식은 병렬적으로 실행되어 먼저 끝나는 함수가 먼저 실행되게 된다.

 

굳이 async await 키워드가 아니더라도 setTimeout으로 의도적으로 시간을 주어 비동기식으로 처리하게 할수도 있다.

class App extends React.Component {
  state = {
    isLoading: true
  };
  // render하면 진행되는 함수이다. 이함수는 setTimeout()함수를 통해 setState()를 6초 후에 시켰다.
  // 즉 data를 fetch 한것이다.

  getMovies = async () => {
    const movies = await axios.get("https://yts.mx/api/v2/list_movies.json");
  }
  componentDidMount() {
    this.getMovies();
  }

  render() {
    const { isLoading } = this.state;
    return (
      <div>{isLoading ? "Loading..." : "We are ready"}</div>
    );
  }
}

위 코드에서 axois.get은 url에서 data를 가져오는 함수이다.

await 과 async 이라는 키워드는 비동기를 구현하는 키워드이다.

 

async : getMovies가 비동기 함수라는 것을 알려주고

await : axios.get("")가 시간이 걸려도 기다려달라는 키워드이다. 

 

  getMovies = async () => {
    const {
      data: {
        data: { movies }
      }
    } = await axios.get("https://yts.mx/api/v2/list_movies.json");
    console.log(movies);
  }
  componentDidMount() {
    this.getMovies();
  }
  getMovies = async () => {
    const movies = await axios.get("https://yts.mx/api/v2/list_movies.json");
    console.log(movies.data.data.movies);
  }
  componentDidMount() {
    this.getMovies();
  }

위 두개 코드는 같다. 근데 위의 코드가 더 ES6 같은 코드라고 한다. (아래코드가 더 보기 편한거 같은데..)

 getMovies = async () => {
    const {
      data: {
        data: { movies }
      }
    } = await axios.get("https://yts.mx/api/v2/list_movies.json");
    this.setState({ movies: movies });
  }

위코드에서 movies : movies는  state 안에 movies라는 요소가 있고 받아온 데이터에도 movies가 있는데

state의 movies에 받아온 데이터의 movies를 넣겠다는 의미이다.

 

하지만 이것은 this.setState({movies}); 로도 가능하다.