개발자를 향해...

[ReactJS로 영화 웹 서비스 만들기] #3 STATE 본문

웹 자바스크립트 공부/ReactJS + node.js

[ReactJS로 영화 웹 서비스 만들기] #3 STATE

eugeneHwang1124 2021. 2. 6. 20:08
728x90
반응형

본 내용은 노마드코더 - ReactJS로 영화 웹 서비스 만들기 를 수강하며 작성되었습니다.

 

state - 동적 데이터

이제 state를 통해 동적 데이터를 만들어보자. 지금까지 만든 모든Food 데이터와 컴포넌트들을 지우고 App 함수를 calss 컴포넌트로 만든다. 선언할 때 extends React.Component 를 넣어서 App을 react component로 만든다. 리액트 컴포넌트가 render을 가지고 있기 때문에 클래스 안에 render를 사용할 수 있다.

import React from 'react';
import PropTypes from 'prop-types';

class App extends React.Component {
  render() {
    return <h1>Im eugene</h1>;
  }
}

export default App;

여기서 class 컴포넌트와 function 컴포넌트의 차이를 보면 class 컴포넌트는 class이고 react Component로부터 확장되고 화면에 표시되지만 function 컴포넌트는 function이고 return을 하며 화면에 표시된다. class 컴포넌트에서는이것을render에 넣어야 한다. class 컴포넌트에서는 자동적으로 모든 class 컴포넌트의 render method를 실행하려고 한다. class 컴포넌트를사용하는이유는state때문이다.

state는 object로 component의 데이터를 넣을 공간으로 값이 변하는 데이터를 넣을 수 있다. 예를 들어 count라는 변수를 만들어보자. 이 기본 값은 0이다. 만들어진 state의 count변수를 render에서 사용하고 싶으면 {this.state.count}라고 호출하여 사용해야한다.

import React from 'react';
import PropTypes from 'prop-types';

class App extends React.Component {
  state = {
    count:0
  }
  render() {
    return <h1>The number is: {this.state.count}</h1>;
  }
}

export default App;

 

이제 state를 사용하는 원래 목적대로 count의 값을 바꾸어보자. Add와 Minus라는 버튼을 만든다. 그리고 버튼이 눌리면 작동할 수 있는 add와 minus라는 함수를 만든 후 onClick={}에 함수를 넣어주었다.

import React from 'react';
import PropTypes from 'prop-types';

class App extends React.Component {
  state = {
    count:0
  }
  add=()=>{
    console.log("add");
  };
  minus=()=>{
    console.log("minus");
  };
  render() {
    return (
      <div>
        <h1>The number is: {this.state.count}</h1>
        <button onClick={this.add}>Add</button>
        <button onClick={this.minus}>Minus</button>
      </div>
      );
  }
}

export default App;

이제 이렇게 만든 함수로 count의 값은 감소하거나 증가시켜보자. 주의할 점은 반드시 state를 직접 변경하면 안된다는 것이다. 직접 변수에 값은 바꾸려해도 react가 render 함수를 다시 호출해 리렌더링 해야하는 데 직접 변경하면 이런 업데이트가 이루어지지 않아서 그렇다. 만약 setState를 사용하면 react는 우리가 언제 setState를 호출할지와  view를 refresh하길 원하는지, 즉 리렌더링 하는지 알고있게 된다.

setState를 사용할 때에는 새로운 state를 받아야하기 때문에 변수값을 1증가시켜 렌더링하는 코드는 다음과 같다.

import React from 'react';
import PropTypes from 'prop-types';

class App extends React.Component {
  state = {
    count:0
  }
  add=()=>{
    this.setState({count:1});
  };
  minus=()=>{
    this.setState({count:-1});
  };
  render() {
    return (
      <div>
        <h1>The number is: {this.state.count}</h1>
        <button style={{height:"30pt" , width:"50pt"}} onClick={this.add}>Add</button>
        <button style={{height:"30pt" , width:"50pt"}} onClick={this.minus}>Minus</button>
      </div>
      );
  }
}

export default App;

이렇게 setState를 호출하면 react는 state를 refresh하고나서 render함수를 호출한다. 그리고 react는 리렌더링 할 때 변화가 생기는 부분만 업데이트한다. 이게 react가 빠른 이유이다.

add=()=>{
    // this.setState({count: this.state.count+1 });
    this.setState( current => ({count: current.count + 1 }));
  };
  minus=()=>{
    this.setState( current => ({count: current.count - 1 }));
  };

 

LifeCycle API

컴포넌트가 생성될 때 render 전에 호출되는 몇가지 함수들이 있다. 또한 컴포넌트가 업데이트될 때 호출되는 컴포넌트들이 있다. 이것들 중에 중요한 몇가지를 배워보자.

1. mounting 

- constructor

  : 자바스크립트에서 class를 호출할 때 생성되는 것이다. render보다 먼저 호출된다.

import React from 'react';
import PropTypes from 'prop-types';

class App extends React.Component {
  
  constructor(props){
    super(props);
    console.log("생성자");
  }
  
  render() {
    console.log("렌더링");
    return (<div></div>);
    }
}

export default App;

콘솔창

- getDerivedStateFromProps( )

- render( )

-componentDidMount( )

  : render 이후 호출되며 이 컴포넌트가 처음 render 되었음을 알려준다.

import React from 'react';
import PropTypes from 'prop-types';

class App extends React.Component {

  constructor(props){
    super(props);
    console.log("생성자");
  }

  componentDidMount(){
    console.log("didmount");
  }
  
  render() {
    console.log("렌더링");
    return (<div></div>);
  }
}

export default App;

2.Updating

우리가 add나 minus함수로 state를 변경해 컴포넌트가 업데이트 되었을 때 실행

- componentDidUpdate

  : render 후에 업데이트가 발생하여 완료되면 호출된다. 

import React from 'react';
import PropTypes from 'prop-types';

class App extends React.Component {

  constructor(props){
    super(props);
    console.log("생성자");
  }

  componentDidMount(){
    console.log("didmount");
  }

  componentDidUpdate(){
    console.log("업뎃됨!");
  }
  
  render() {
    console.log("렌더링");
    return (<div></div>);
  }
}

export default App;

add나 minus 버튼을 눌렀을 때

3.Unmounting

컴포넌트가 죽는 것을 의미한다. (state를 교체할 때 등...)

- componentWillUnmount

  : 다른 페이지로 넘어가는 등 컴포넌트가 종료될 때 호출된다.

 

state변수에 대해 조건문을 사용해보자. 그런데 여기서 render의 return 속에서 호출할 때마다 변수 앞에 this.render를 붙여야하는 귀찮음이 있다. 이 부분은 다음과 같이 해결이 가능하다.

import React from 'react';
import PropTypes from 'prop-types';

class App extends React.Component {
  state = {
    isLoading: true
  }
  
  render() {
    const { isLoading}=this.state;
    return (
      <div>
        { isLoading ? "true" : "false"}
      </div>
      );
  }
}

export default App;

여기에 render후 6초 뒤에 setState로 isLoading 값을 false로 바꾸어보면

componentDidMount() {
  setTimeout(()=>{
    this.setState({isLoading:false});
  },6000)
}

브라우저의 값이 false로 바뀐 것을 확인할 수 있다.

이제 우리가 할 일은 componentDidMount에서 데이터를 fetch하는 것이다. 그리고 데이터 패치가 완료되면 flase를 출력하는 대신 map을 만들고 movie 정보를 렌더하면 된다. 다음에 이어서 진행하자.

 

 

반응형