[TIL] 20210511_Side Effect (feat. API 호출)

BANSEOK SUH·2021년 5월 11일
0

TIL

목록 보기
12/22
post-thumbnail

Side Effect란?

"함수(또는 컴포넌트)의 입력 외에도 함수의 결과에 영향을 미치는 요인"입니다.
대표적으로 네트워크 요청, API 호출이 그러합니다.

이번에는 검색 기능을 구현하고, 검색어를 통해 YouTube API를 호출하고, 전달받은 데이터를 렌더링하겠습니다.

검색 기능

여기에선 이전 포스트에서 다루었던 state 끌어올리기 개념이 반영됩니다.

변화해야 할 상태와 상태를 변화시킬 함수는 상위 컴포넌트에 있지만, 검색어는 하위 컴포넌트에서 다루기 때문입니다.


하위 컴포넌트인 Search 컴포넌트를 살펴보겠습니다.

참고: Search 컴포넌트는 상위 컴포넌트로부터 handleButtonClick이라는 함수를 전달받았습니다.

// 내부적으로 상태를 다루어야 하기 때문에 클래스 컴포넌트를 사용했습니다.
class Search extends React.Component {
  // 생성자 함수
  constructor(props) {
    super(props);
    this.state = { // Search 컴포넌트 내부에서 상태를 정의합니다. 추후에 이 상태를 상위 컴포넌트로 끌어올립니다.
      queryString: ''
    };
  }
  
  // Search 컴포넌트 내부에서 상태를 변화시킬 함수
  changeHandler(data) {
    ...
  }

  // 렌더링
  render() {  
    return (
      <div className="search-bar form-inline">
        <input className="form-control" type="text" onChange={(event) => this.changeHandler(event.target.value)} />
        <button className="btn hidden-sm-down" onClick={() => this.props.handleButtonClick(this.state.queryString)}>
          검색
        </button>
      </div>
    )
  }
}

렌더할 input 태그에는 onChange 이벤트를 사용해, 값이 변할 때마다 state를 변화시키는 이벤트를 걸어줍니다. changeHandler 함수가 매번 실행되면서 state를 변경시킵니다.
이벤트가 발생한 지점의 값을 가져와야 하기 때문에 콜백함수를 사용해서 값(event.target.value)을 인자로 전달해주고 있습니다.

button 태그에는 onClick 이벤트를 사용해, 상위 컴포넌트로부터 전달받은 함수를 실행시킵니다. 현재 컴포넌트의 state를 끌어올려줘야 하기 때문에 역시 콜백함수를 사용했고, 값(this.state.queryString)을 인자로 전달해줍니다. 여기서의 값은 input 박스에 마지막으로 남아있는 값입니다.


API 호출

상위 컴포넌트인 App은 대략 이렇게 생겼습니다.

class App extends React.Component {
  constructor(props) {
    ...
  }

  // 컴포넌트가 화면에 등장한 직후에 호출되는 함수입니다.
  // API 호출을 할 때에는 보통 이 곳에서 호출을 합니다.
  componentDidMount() {
    this.searchVideo('무한도전')
  }

  setCurrentVideo(video) {
    ...
  }

  // 검색 결과를 반영해 상태를 변경하는 함수
  searchVideo(queryString) {
    ...
  }

  render() {
    return (
      <div>
        <Nav handleButtonClick={this.searchVideo}/>
        ...
      </div>
    )
  }
}

렌더할 Nav 컴포넌트로부터 끌어올려진 state는 searchVideo 함수의 인자(queryString)로 전달됩니다. 이렇게 하위 컴포넌트의 state가 상위 컴포넌트로 끌어올려졌습니다.

여기서 끝이 아니죠. searchVideo 함수 내부에서는 전달받은 검색 결과를 이용해 YouTube에 API를 요청합니다
searchVideo 함수를 살펴보겠습니다.

searchVideo(queryString) {
  // fetch를 이용한 API GET 요청   
  fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&key=[API 키]&q=${queryString}&type=video&videoEmbeddable=true`)
    .then((data) => data.json()) // 데이터 전달 받아 json 형식으로 변환
    .then((json) => {
      setTimeout(() => { // loading 화면을 위한 setTimeout 메서드
        this.setState({  
          isLoading: false,
          videos: json.items // setState 메서드를 이용해 전달받은 데이터로 상태를 변화시킵니다.
        });
      }, 1000)
    })
}

YouTube API 키를 발급받는 방법은 따로 이야기하지 않겠습니다.

하위 컴포넌트로부터 끌어올려진 데이터(queryString)를 fetch url의 쿼리로 전달하여 검색어에 따른 데이터를 요청합니다.

여기서 중요한 부분은, 끌어올려진 데이터를 fetch url의 쿼리로 전달하여 API를 요청하고, fetch 함수를 통해 데이터를 전달받고, 데이터를 json화 시켜서, 그 데이터를 이용해 상태를 변경시켰다는 것입니다.

여기까지 YouTube API 호출을 통해 데이터를 잘 전달받고 상태를 변경시켰습니다.


렌더링

사실 따로 렌더링을 위해 처리해야 할 작업이 없습니다.
왜냐하면 상태가 변하면 자동으로 렌더링이 되기 때문입니다.

다음의 그림을 참고하죠. 외워두는 것이 좋겠습니다.

보이는 것과 같이, setState로 컴포넌트가 update 되면, 자동 렌더링이 됩니다.

profile
HelloBanny

0개의 댓글

관련 채용 정보