여씨의 개발이야기

[입문] class형 function형 컴포넌트의 차이 본문

🐾 Programming Lang/🌐 React

[입문] class형 function형 컴포넌트의 차이

yeossi 2022. 1. 10. 16:50

react 컴포넌트를 선언할 때 두 가지 방법이 있다. 바로 class방법과 function방법이다.

19년부터 function형 컴포넌트에 hook을 지원하면서 지금은 공식 문서에서 공개적으로 function형 컴포넌트와 hook을 같이 사용할 것을 권장하고 있다. 그렇지만, class를 자주 사용하지 않더라도 아직까지 사용하는 기업들이 있다. 그 프로젝트의 유지보수를 위해서는 클래스형 컴포넌트에 대한 개념은 알고 있어야한다. 

1. function형 컴포넌트

import React from 'react';

function App() {
  const contents = 'hi';
  return <div>{contents}</div>;
}

export default App;

function형 컴포넌트는 class형 컴포넌트에 비해 선언문이 쉽고, 메모리 자원을 덜 사용한다. function형 컴포넌트가 처음 나왔을 때에는 state와 lifecycle API를 사용할 수 없었지만, 이는 앞에 언급한 react hook이 도입되면서 해결됐다.

 

2. class형 컴포넌트

import React, { Component } from 'react';

class App extends Component {
  render() {
    const contents = 'hi';
    return <div>{contents}</div>;
  }
}

export default App;

class형 컴포넌트는 state, lifecycle API를 사용할 수 있고, 임의 메서드를 정의할 수 있다. 또한 render 함수가 반드시 있어야 하며, 그 안에서 보여줘야 할 JSX를 반환해야 한다. ES6 문법 부터 이전의 prototype을 이용해 구현하던 class 문법을 사용하여 구현할 수도 있다.

 

3. functional components vs class components 분석 비교 참고문서

출처 : https://techdoma.in/react-js/functional-components-vs-class-components

Defining state of component

This is one of the biggest and most important difference between a functional component and class component. We cannot define state of the component inside a functional component. We can only do so in the class component.

class Welcome extends React.Component {
  state = {
    name: 'Techdomain'
  }
  render() {
    return <h1>Hello, {this.state.name}</h1>;
  }
}

Adding state to the component is necessary when you want the component to render again when the state is changed. In the above example, we can also store the name value inside a variable in a functional component. But if the name component changes (maybe due to external api or user input), then component would not rerender.

Using references inside component

In React, we can use the refs to integrate uncontrolled componnent or 3rd party libraries. Props are the only way to pass data between component. But there are few cases where we cannot use the props, and modify the child imperatively (instead of declarative way).

Using Refs for a class component

class CustomTextInput extends React.Component {
  // ...
}

class AutoFocusTextInput extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }

  componentDidMount() {
    this.textInput.current.focusTextInput();
  }

  render() {
    return (
      <CustomTextInput ref={this.textInput} />
    );
  }
}

Using refs for a funtional component - But the below code will not work

function MyFunctionComponent() {
  return <input />;
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.textInput = React.createRef();
  }
  render() {
    // This will *not* work!
    return (
      <MyFunctionComponent ref={this.textInput} />
    );
  }
}

Using hooks inside component

There are several problems of using classes in React. Class components do not minify well, they make hot reloading of modules flaky and unreliable.

Hooks allow use of React's features without using classes. Hooks embrace functional components. Hooks provide features of React like state, lifecycle methods inside a funtional component.

You cannot use hooks inside a class component, as class component itself provides all the features of React like state and lifecycle methods.

import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

In the above code, we define the state count with the initial value of 0 (passed as param inside useState hook). Rest of code is similar to a functional component. Main point to note here is that, even though it is a functional component, we are able to use the React's feature of state using hooks.

Using lifecycle methods

In a class component, we can use lifecycle methods like componentDidMount, componentWillUnMount

import React, { Component } from 'react';

class Example extends Component{
  state = {
    name: ''
  }
  componentDidMount(){
    this.setState({
      name: 'Techdomain'
    })
  }
  render(){
    return <div>{this.state.name}</div>
  }
}

In a functional component, it is not possible to use lifecycle methods without hooks. Just like state hook, React offers different hooks called effect hook which can be used to update the component.

import React, { Component } from 'react';

function Example(){
  const [name, setName] = useState('');

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(()=>{
    setName('Techdomain');
  })
  return <div>{name}<div>;
}

Conclusion

Although earlier some features of React were not available inside a functional component, now with React 16.8, you can use those features using hooks. Given the drawbacks of class components like improper minification of code and flaky hot reloading, it is now more preferable to use functional components with hooks.

Comments