림찌의 개발일기 💻

[React.js] 클래스 컴포넌트(class)와 함수형 컴포넌트 (hook) 본문

React

[React.js] 클래스 컴포넌트(class)와 함수형 컴포넌트 (hook)

림찌 🥰 2021. 6. 10. 12:48

 

클래스형 컴포넌트와 함수형 컴포넌트의 비교를 위해 

간단한 끝말잇기 예제를 가져왔다. 

 

클래스형 컴포넌트

class WordRelay extends Component{
  
  state = { //state를 먼저 이렇게 선언  
  	word: '리액트',
    value: '',
    result: '',
  };
  
  // 끝말잇기 오답 체크
  onSubmitForm = (e) => {
    e.preventDefault();
    if(this.state.word[this.state.word.length - 1] === this.state.value[0]{
      //마지막 word의 첫번째와 지금 적은 값의 첫번째가 같으면 실행
      this.setState({
      	result: '딩동댕, 이어서 작성해주세요', //정답일시 나오는 문구
        word: this.state.value, 
        value: '', // 값 리셋
      });
      this.input.focus(); //input에 포커싱 되도록
    }else{
      this.setState({
        result: '땡! 틀렸습니다!',
        value: '',
        //틀렸으므로 word의 값은 변경되지 않는다.
      });
      this.input.focus();
    }
  };
  
  onChangeInput = (e) => {
    this.setState({ value: e.target.value });
  };
  
  input; //이렇게 input을 선언해주어야한다
  onRefInput = (c) => {
   this.input = c;
  };
  
  render(){
  	return(
      <>
      	<div>{this.state.word}</div>
        <form onSubmit={this.onChangeForm}>
          <input ref={this.onRefInput} value={this.state.value} onChange={this.onChangeInput} />
          <button>입력</button>
        </form>
        <div>{this.state.result}</div>
      </>
    )
  }
  
}

클래스형 컴포넌트의 예제코드를 보면 state나 함수를 불러올때 앞에 this 가 무조건 붙어서 온다.

그리고 클래스형 컴포넌트는 jsx를 불러올때 render() 로 꼭 감싸주어야한다. render 안에서 JSX를 불러오기 때문이다.

그리고 지금 예제에서 다루진 않았지만 component 안에 라이프사이클(life-circle) 기능을 넣을 수 있다.

 

 

함수형 컴포넌트 (hook)

const { useState, useRef } = React; //hook을 사용할땐 이렇게 위에서 구조분해할당으로 불러와준다.

const WordRelay = () => {
  
  //hook의 state 선언
  const [word, setWord] = useState('리액트');
  const [value, setValue] = useState('');
  const [result, setResult] = useState('');

  const inputRef = useRef(null);


  const onSubmitForm = (e) => {
    e.preventDefault();
    if (word[word.length - 1] === value[0]) {
        //정답
        setResult('딩동댕');
        setWord(value);
        value('');
        inputRef.current.focus(); //hooks 에는 current 꼭 붙여줘야한다.
    } else {
        //오답
        setResult('땡!');
        setValue('');
        inputRef.current.focus();
        }
    };

    const onChangeInput = (e) => {
      setValue(e.target.value)
    };


    // hook는 render 필요옶음
    return (
      <>
        <div>{word}</div>
          <form onSubmit={onSubmitForm}>
            <label id="label" htmlFor="wordInput">글자를 입력하세요</label>
            <input id="wordInput" className="wordInput" ref={inputRef} value={value} onChange={onChangeInput} />
            <button >입력</button>
          </form>
        <div>{result}</div>
       </>
    )
}

 

위의 클래스형 컴포넌트를 함수형 컴포넌트로 변경한 것이다.

간단한 예제이지만 함수형 컴포넌트가 클래스형 컴포넌트보다 간략하게 적힌다는 걸 확인할 수 있을 것이다.

함수형 컴포넌트는 state나 함수를 불러올때 `this`, `this.state` 와 같은 것이 필요없다.

 

useState 함수로 state를 사용하기 때문이다. useState 함수를 호출하면 배열이 반환되는데
첫번째 인자는 현재 상태, 두번째 인자는 상태를 바꿔주는 함수이다.

const [word, setWord] = useState('리액트');

위 예제에서 이부분이다. word가 현재 상태, setWord 가 상태를 바꿔주는 함수다.

(초기값에 '리액트' 를 넣어주었으므로 word의 초기 상태는 문자열 '리액트' 이다.)

그래서 오답/정답을 판단하고 변경된 값을 보여줄때 setWord, serResult... 등등을 사용한 것이다.

 

클래스형 함수형
state 기능 사용 (setState) state 사용 (hook: useState)
render() 안에서 jsx 불러옴 render() 필요없음
life-cycle 사용 life-cycle 대신 hook 사용

 

큰 특징은 이렇게 있다.

주의할 점은 함수형 컴포넌트에서 hook을 사용할때 항상 위에서 구조분해할당으로 해당 hook을 불러와주어야한다는 점!!

 

 

리액트 공식문서에선 함수형 컴포넌트인 hook 사용을 권장하고 있다고 한다.
그러나 나중에 예전 프로젝트를 유지보수해야할때 클래스형 컴포넌트를 마주칠수 있으니 알아두는 것이 좋다.
나도 두개 다 사용해본 결과 함수형 컴포넌트가 훨씬 간편하다는 느낌이다...
라이프사이클까지 들어가면 클래스형은 좀더 코드가 꼬이는 느낌...?
Comments