개발/엘리스 AI 트랙

엘리스 AI 트랙 07주차 - React 기초 IV (2/5) 🔥

Max 2021. 2. 15. 23:27
반응형

✔ 07주차. 웹 프론트엔드 II

<학습 목표>

  1. 클래스 컴포넌트와 함수 컴포넌트의 공통된 점과 차이점을 비교하여 상황에 맞게 사용할 수 있습니다.

  2. Hook을 사용해 함수 컴포넌트에서도 State의 값을 변경할 수 있습니다.

  3. State관리를 하는 방법과 구조를 이해하고 Redux를 사용하는 이유를 알 수 있습니다.


[01 State Hook 사용하기]

1. Hook과 함수형 컴포넌트
  - Hook은 React state를 함수 안에서 사용할 수 있게 함. (클래스 안에서 동작X)
  - Hook 사용하기 : 사용할 Hook을 import (ex. import React, { useState } from 'react'; )

// useState import
import React, { useState } from 'react';

function Example() {
  // State 변수 선언
  const [count, setCount] = useState(0);
  
  return (
    <div>
      {/* State 가져와서 출력 */}
      <p>You clicked {count} times</p>
        {/* setCount() 사용해 count 를 갱신 */}
        <button onClick={() => setCount(count+1) }>
          Click me
        </button>
    </div>
  )
}

ReactDOM.render(<Example />,document.getElementById('root'));

  - State Hook 팁

    ① 배열 구조 분해 : State 변수 선언시 대괄호를 이용하는데, 이런 자바스크립트 문법을 구조 분해 할당 중에서도 배열 구조 분해라고 함

var fruitStateVariable = useState('banana'); // 두 개의 아이템이 있는 쌍을 반환
var fruit = fruitStateVariable[0]; // 첫 번째 아이템
var setFruit = fruitStateVariable[1]; // 두 번째 아이템

// 위 코드와 아래 코드는 동일함
const [fruit, setFruit] = useState('banana');

    ② 여러 개의 State 변수를 사용하기 : 이름이 다른 여러 개의 State 변수를 선언할 수 있음

function ExampleWithManyStates() {
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
}

 

[02 Effect Hook 사용하기]

1. Effect Hook

  - Effect Hook : 클래스형 컴포넌트의 생명주기 메소드인 componentDidMount, componentDidUpdate, componentWillUnmount가 합쳐진 것. 

import React, { useState, useEffect } from 'react';

function HideAndSeek() {
  useEffect(() => {
    // Mounting 및 Updating 시 실행할 코드
    alert('토끼를 찾았습니다!');
    return function hide() {
      // Unmounting 시 실행할 코드
      alert('토끼가 숨었습니다.');
    }
  });
  
  return "토끼 등장";
}

function App() {
  const [mounted, setMounted] = useState(true);
  
  const toggle = () => setMounted(!mounted);
  let find_rabbit;
  let print_img;
  if(mounted) {
    find_rabbit = <HideAndSeek/>
    print_img = <img src= {rabbit}/>    
  }
  else {
    print_img = null;
  }
  return (
    <div>
      <button onClick={toggle}>숨기/찾기</button>
      <br/>
      {find_rabbit}
      {print_img}
    </div>
  );
}

ReactDOM.render(<App />,document.getElementById('root'));

2. 정리(Clean-up)
  - 정리란 클래스형 컴포넌트에서 Unmounting시 componentWillUnmount를 이용해서 더 이상 사용하지 않는 컴포넌트를 해제하는 것

  - React 컴포넌트에는 정리(Clean-up)가 필요한 것과 그렇지 않은 것 두 종류의 side effects가 있음

  - 정리가 필요하지 않은 side effects : React가 DOM을 업데이트한 뒤 추가로 코드를 실행해야 하는 경우 side effects 정리 필요X

  - 정리를 이용하는 side effects : React가 DOM을 업데이트한 뒤 추가로 코드를 실행할 필요가 없으면 정리 필요O (정리 안하면 경우에 따라 메모리 누수가 발생할 수 있음)

 

3. 정리가 필요하지 않은 경우

  - 정리가 필요 없는 컴포넌트 : React가 DOM을 업데이트한 뒤 추가로 코드를 실행해야 하는 경우가 있어 side effects 정리가 필요 없는 컴포넌트 (컴포넌트가 Unmounting된 후 호출되는 componentWillUnmount()가 따로 필요 없는 경우)

    ① 정리가 필요 없는 클래스형 컴포넌트

mport React from 'react';

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
  
  componentDidMount() {
    alert(this.state.count + '번 클릭했습니다.');
  }

  componentDidUpdate() {
    alert(this.state.count + '번 클릭했습니다.');
  }

  render() {
    return (
      <div>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          버튼 클릭
        </button>
      </div>
    );
  }
}

ReactDOM.render(<Counter />,document.getElementById('root'));

    ② 정리가 필요 없는 함수형 컴포넌트

//  Effect Hook 구현하기 위해 useEffect import
import React, { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    alert(count + '번 클릭했습니다.');
  });

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>
          버튼 클릭
        </button>
      </div>
  );
}

ReactDOM.render(<Counter />,document.getElementById('root'));

4. 정리가 필요한 경우

  - 정리 : 클래스형 컴포넌트에서 Unmounting시 componentWillUnmount()를 이용해서 더 이상 사용하지 않는 컴포넌트를 해제하는 것

    ① 정리가 필요한 클래스형 컴포넌트

class Container extends React.Component {
  constructor(props) {
    super(props);
    this.state = {show: true};
  }
  delHeader = () => {
    this.setState({show: false});
  }
  render() {
    let myheader;
    if (this.state.show) {
      myheader = <Child />;
    };
    return (
      <div>
        {myheader}
        <button type="버튼" onClick={this.delHeader}> Delete Header </button>
      </div>
    );
  }
}

class Child extends React.Component {
  componentWillUnmount(){
    alert('텍스트가 제거 되었습니다!')
  }
  
  render() {
    return (
      <p>버튼을 클릭해 해당 텍스트를 제거하세요.</p>
    );
  }
}

ReactDOM.render(<Container />,document.getElementById('root'));

    ② 정리가 필요한 함수형 컴포넌트

// 클래스형 컴포넌트에서 componentWillUnmount() 메소드를 통해 실행하던 코드를
// useEffect를 이용해 실행
import React, { useState, useEffect } from 'react';

function Container() {
  const [show, setShow] = useState(true);
  
  let myheader;
  if (show) {
    myheader = <Child />;
  }
  
  return (
    <div>
    {myheader}
    <button onClick={() => setShow(false)}>버튼</button>
    </div>
  );
}

function Child() {
  useEffect(() => {
    // Mounting 및 Updating 시 실행할 코드
    return function cleanup() {
      // Unmounting 시 실행할 코드
      alert('텍스트가 제거 되었습니다!');
    }
});
  
  return (
    <p>버튼을 클릭해 해당 텍스트를 제거하세요.</p>
  );
  
}

ReactDOM.render(<Container />,document.getElementById('root'));

※ 수업 자료의 출처는 K-Digital Training x 엘리스 인공지능 서비스 개발 기획 1기 (elice.io/)입니다.

반응형