리액트 강좌: 함수

리액트는 사용자 인터페이스를 구축하기 위해 많이 사용되는 JavaScript 라이브러리입니다. 리액트를 이해하고 활용하기 위해서는 함수의 개념을 명확히 이해하는 것이 중요합니다. 본 강좌에서는 리액트에서 함수가 어떻게 사용되는지에 대해 자세히 다루고, 현대 웹 개발에서 함수형 프로그래밍이 어떻게 적용되는지에 대해 알아보겠습니다.

1. 리액트에서 함수의 정의

리액트에서 함수는 상태를 관리하거나 화면을 업데이트하는데 필요한 로직을 포함하는 기본 단위입니다. 리액트는 함수형 컴포넌트를 사용하여 UI를 정의할 수 있도록 지원합니다. 함수형 컴포넌트는 JavaScript 함수로, 이 함수에서 JSX를 반환하여 화면에 렌더링합니다. 함수형 컴포넌트는 간단하고 직관적이며, 리액트의 훅(Hook) 기능을 통해 상태와 생명주기 메서드를 사용할 수 있습니다.

2. 함수형 컴포넌트 vs 클래스형 컴포넌트

리액트는 주로 두 가지 방식으로 컴포넌트를 정의할 수 있습니다: 클래스형 컴포넌트와 함수형 컴포넌트입니다. 클래스형 컴포넌트는 ES6 클래스를 사용하여 정의되며, 유지 관리 및 테스트가 어렵고 코드 양이 상대적으로 많아지는 경향이 있습니다. 반면, 함수형 컴포넌트는 단순하고 가벼우며, 코드가 짧아 유지 관리가 용이합니다.

함수형 컴포넌트는 다음과 같이 정의됩니다:


function MyComponent() {
    return <div>Hello, World!</div>;
}

클래스형 컴포넌트는 다음과 같이 정의됩니다:


class MyComponent extends React.Component {
    render() {
        return <div>Hello, World!</div>;
    }
}

3. 함수형 컴포넌트의 장점

  • 단순성: 함수형 컴포넌트는 더 적은 코드로 작성할 수 있으며, 이해하기 쉽습니다. 특히 복잡한 상태 관리 없이 UI를 간단하게 렌더링 할 수 있습니다.
  • 성능 최적화: 리액트는 함수형 컴포넌트를 메모이제이션(memoization)하여 최적화 할 수 있습니다. 이를 통해 다시 렌더링할 필요가 없는 경우 컴포넌트를 건너뛸 수 있어 성능을 크게 향상시킬 수 있습니다.
  • 사이드 이펙트 관리: 훅을 통해 부수 효과를 관리할 수 있어 상태 관리가 간편해집니다.

4. React Hook을 통한 상태 관리

리액트 16.8버전부터 도입된 훅(Hook)은 함수형 컴포넌트에서 상태를 관리할 수 있는 가장 효과적인 방법입니다. 가장 많이 사용하는 훅은 useState와 useEffect입니다.

4.1 useState 훅

useState는 상태 변수를 추가하고, 상태를 업데이트할 수 있는 함수를 반환합니다. 사용 방법은 다음과 같습니다:


import React, { useState } from 'react';

function Counter() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>현재 카운트: {count}</p>
            <button onClick={() => setCount(count + 1)}>증가</button>
        </div>
    );
}

4.2 useEffect 훅

useEffect는 컴포넌트가 렌더링될 때마다 특정 작업을 수행할 수 있게 해주는 훅입니다. 다음은 useEffect를 사용하는 예시입니다.


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

function Timer() {
    const [seconds, setSeconds] = useState(0);

    useEffect(() => {
        const interval = setInterval(() => setSeconds(s => s + 1), 1000);
        return () => clearInterval(interval);
    }, []);

    return <p>경과 시간: {seconds}초</p>
}

5. 고급 Hooks

useReducer, useContext와 같은 고급 훅을 사용하면 더욱 복잡한 상태 관리가 필요할 때 유용합니다. 특히 useReducer는 복잡한 상태 로직이나 여러 하위 값을 관리할 때 유용합니다. 예를 들어, todo 리스트를 관리하는 데 사용할 수 있습니다.


import React, { useReducer } from 'react';

const initialState = { todos: [] };

function reducer(state, action) {
    switch (action.type) {
        case 'ADD_TODO':
            return { todos: [...state.todos, action.todo] };
        default:
            throw new Error();
    }
}

function TodoApp() {
    const [state, dispatch] = useReducer(reducer, initialState);
    
    const addTodo = todo => dispatch({ type: 'ADD_TODO', todo });

    return (
        <div>
            <h1>To Do List</h1>
            <button onClick={() => addTodo('새 할 일')}>추가</button>
            <ul>
                {state.todos.map((todo, index) => <li key={index}>{todo}</li>)}
            </ul>
        </div>
    );
}

6. 함수형 프로그래밍의 기본 원칙

리액트는 함수형 프로그래밍 패러다임을 따르는 경향이 있습니다. 여기 몇 가지 기본 원칙을 살펴보겠습니다.

  • 순수 함수: 출력이 항상 입력에만 의존해야 합니다. 외부 상태에 영향을 주어서는 안 됩니다.
  • 상태 불변성: 상태를 직접 변경하지 않고 새로운 상태를 반환합니다.
  • 고차 함수: 함수를 인자로 받거나 함수를 반환하는 함수를 의미합니다. 리액트에서는 props를 통해 컴포넌트를 전달하는 방식이 여기에 해당합니다.

7. 결론

리액트는 함수형 프로그래밍 패러다임을 따르며, 함수형 컴포넌트를 통해 UI를 정의하고 상태를 관리하는 데 많은 장점을 제공합니다. 이 강좌를 통해 함수형 컴포넌트의 정의와 장점, React Hooks, 그리고 함수형 프로그래밍의 주요 원칙을 살펴보았습니다. 리액트에서 함수를 잘 활용한다면, 더 효율적이고 관리하기 쉬운 애플리케이션을 구축할 수 있을 것입니다.

더 많은 정보를 원하시면 공식 리액트 문서(여기)를 참조하시기 바랍니다.