React-Native

3. React Hook(1) useState(), useEffect()

Daesiker 2021. 1. 22. 17:48
반응형

3-1 Hook이란?

함수형 컴포넌트에서 State와 생명주기(Life Cycle)을 연동(hooking)한 함수입니다.

Hook은 class를 작성하지 않고도 state와 다른 React의 기능들을 사용할 수 있습니다.

기존의 class형 컴포넌트도 사용은 가능하지만 가급적으로 새로 만드는 프로젝트는 Hook으로 사용하길 권장하고 있기 때문에 우리는 React, React-Native를 배우기전에 Hook을 공부할 필요가 있습니다.

https://levelup.gitconnected.com/an-introduction-to-react-hooks-50281fd961fe


3-2 React Hook을 사용하는 이유

  1. 기존 React에서는 State와 관련된 로직을 재사용하기 어렵다.

    로직을 재사용하기 위해 Component를 감싸는 Wrapper가 많아 불편하다.

    →Hook을 사용하면 컴포넌트 자체에서 State로직을 추상화 할 수 있고,

컴포넌트의 계층 변화 없이 로직을 재사용할 수 있게 해준다.

2. 복잡한 생명주기(LifeCycle)을 이해하기 어렵다.

각각 생명주기마다 기본적인 메서드가 있어서 원하는 로직을 특정한 타이밍에, 해당하는 로직만 실행시키기 어렵다.

ex) 데이터를 가져오는 로직 componentDidMount와 componentDidUpdate에서 수행할 수 있지만 언제 어느 곳에서 로직을 수행해야 할지 특정할 수 없다.

→ Hook을 사용하면 함수로 컴포넌트를 나눌 수 있다.

적절한 생명주기가 이미 Hooking 되어있어서 생명주기 안에서 어떤 일이 일어나는지 알 필요가 없다.

3. 클래스의 불편함

class는 javascript에서 this와 event handler의 동작을 정확히 알아야 하고, 컴포넌트와 함수를 언제 어떻게 사용해야하는지 알아야 문제가 생기지 않는다.

→ Hook과 함수형 프로그래밍을 사용하면 문법이 더 자유롭고, 코드의 분리와 재사용을 원하는대로 할 수 있다.

💡
아직은 무슨말인지 모를 수 있습니다. 밑에서 자세히 설명해 드릴게요!!


3-3 React Hooks

함수형 컴포넌트에서 Hook의 사용

  1. 화살표 함수 사용
    const Example = (props) => {
    	//여기서 Hook을 사용할 수 있다.
    	return <div />;
    }

  1. 일반 함수 사용
    function Example(props) {
    	//여기서 Hook을 사용할 수 있다.
    	return <div />
    }

    함수형 컴포넌트는 State가 없는 컴포넌트지만, Hook이 State를 함수안에서 사용할 수 있게 해줍니다.

    Hook은 Class 안에서는 사용할 수 없다.

    서른은 여기까 이제부터 본격적으로 시작하겠습니다.


    3-4 useState

    🔻 useState()

    import React, { useState } from 'react';
    
    function Example() {
    	const [age, setAge] = useState(42);
    	const [fruit, setFruit] = useState('banana');
    	const [todos, setTodos] = useState({text: 'Learn Hooks'});
    // ....
    }

    🔻 React.Component

    class Example extends React.Component {
    	constructor(props) {
    		super(props);
    		this.state = {
    			age: 42,
    			fruit: 'banana',
    			todos: {text : 'Learn Hook'},
    		}
    	}
    }

    위 2코드는 동일한 코드이다. 둘다 state안에 age, fruit, todos라는 변수가 생성되었다. 다른 점은 state를 바꾸는 함수이다. 기존의 코드 같은 경우는 this.setState()를 통해서 바꿔주었지만 useState()같은 경우에는 setState()의 명을 변경이 가능하다.

    🔻 useState()

    💡
    const [state명, setState명] = useState(초기값)

    React.Component state안에 변수가 여러개 있을때 this.setState에 들어가서 this.state.age 이런식으로 접근을 해야하는데 useState를 사용하면 변수당 하나의 setState가 있기 떄문에 훨씬 편하게 접근이 가능하다.

    아래는 setState를 비교한 코드이다.

    ⚫ Class Component

    <button onClick={() => this.setState({count: this.state.count + 1})}>
    	Click me
    </button>

    ⚫ Function Component

    <button onClick={() => this.setCount(count + 1)}>
    	Click me
    </button>

    → class는 state값이 많으면 많을수록 복잡하고 햇갈릴 수 있는데 function은 변수마다 함수가 지정되어있어서 편하게 사용할 수 있다.


    3-5 useEffect

    기본적인 개념은 React Component에 componentDidMount와 componentDidUpdate와 동일한 동작을 합니다. 하지만 ReactComponent에서는 Side Effect는 함수형 컴포넌트 안에서는 허용되지 않습니다.

    💡
    Side Effect : 데이터를 받거나, 구독하기, 혹은 DOM을 직접 조작하는 행위

    그래서 useEffect Hook에 함수를 전달하여 렌더링 완료 후 수행되게 합니다. componentDidMount와 componentDidUpdate와는 다르게 useEffect로 전달된 함수는 지연 이벤트 동안에 레이아웃 배치와 렌더링을 완료한 후 실행됩니다.

    ⚫ Class Component

    class Example extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          count: 0
        };
      }
    
      componentDidMount() {
        document.title = `You clicked ${this.state.count} times`;
      }
      componentDidUpdate() {
        document.title = `You clicked ${this.state.count} times`;
      }
    
      render() {
        return (
          <div>
            <p>You clicked {this.state.count} times</p>
            <button onClick={() => this.setState({ count: this.state.count + 1 })}>
              Click me
            </button>
          </div>
        );
      }
    }

    Class형 컴포넌트에서는 초기 실행시에는 componentDidMount()로 인해 렌더링이 되어서 웹페이지의 타이틀이 this.state.count가 되고 카운트가 변할때는 componentDidUpdate()로 인해 타이틀이 바뀐다.

    ⚫ Function Component

    import React, { useState, useEffect } from 'react';
    
    function Example() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        document.title = `You clicked ${count} times`;
      });
    
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }

    Function형 컴포넌트에서는 초기 생성, 업데이트에 상관없이 렌더링이 되기만 하면 useEffect를 실행하여 웹의 타이틀이 변경되는 것을 알 수 있다.

    ❓    
    useEffect에서 컴포넌트 생성과 업데이트를 구분하고 싶다면???

    useEffect(() => {
      document.title = `You clicked ${count} times`;
    }, [count]);

    전에 배웠을 떄 componentDidUpdate()는 prevProps나 prevState라는 파라미터를 받아와서 이전값과 비교할 수 있었습니다. useEffect도 2번째인자에 사용하고 있는 state값을 넣으면 비교가 가능합니다. count는 렌더링 이전의 값을 가지고 있어서 후의 count값이 바뀐다면 첫번째 파라미터의 로직이 실행이 됩니다. 이렇게 된다면 우리는 초기 생성때는 count의 값이 같으니까 렌더링이 된 후에 useEffect()가 실행되지 않는 것을 알 수 있습니다.


    3-6 마치며...

    React Component는 Hook을 위해서 작동원리만 배우고 모든 함수를 다 익히지 않고 넘어갔습니다. 하지만 Hook은 요즘 프로젝트에서 너무 많이 사용하고 있기 때문에 왠만해서는 모든 함수를 다 익히고 React-Native로 넘어갈 것 같습니다.

    이해가 안되시는 부분이 있다면 react docs를 보시면서 공부하시면 더욱 효율적일 것 같습니다.

    지금까지 읽어주셔서 감사합니다. 🙏


반응형

'React-Native' 카테고리의 다른 글

6. React-Native 설치(Mac OS)  (0) 2021.01.26
5. React useContext, useRef, useLayoutEffect, useRuducer  (0) 2021.01.25
4. React memo(), useCallback()  (0) 2021.01.25
2. React Component(리액트 컴포넌트)  (0) 2021.01.22
1.React란??  (0) 2021.01.21