리액트 강좌: 컴포넌트 트리에 데이터 공급하기 및 Context로 To Do 앱 리팩토링하기

리액트는 현대 웹 애플리케이션을 구축하는 데 있어 가장 인기 있는 라이브러리 중 하나입니다. 그 이유는 컴포넌트 기반의 아키텍처, 재사용성, 그리고 복잡한 UI를 쉽게 관리할 수 있는 방법 때문입니다. 이번 강좌에서는 리액트의 Context API를 활용하여 컴포넌트 트리에 데이터를 공급하는 방법과 이를 통해 간단한 To Do 애플리케이션을 리팩토링하는 방법에 대해 알아보겠습니다.

1. 리액트 기본 개념

리액트는 UI를 구성하는 컴포넌트의 집합입니다. 컴포넌트는 상태(state)와 속성(props)을 가지며, 이 둘을 통해 UI가 어떻게 렌더링될지를 결정합니다.

1.1 상태와 속성

상태는 컴포넌트의 내부 데이터를 나타내며, 사용자의 입력이나 네트워크 요청에 따라 변경될 수 있습니다. 반면, 속성은 부모 컴포넌트로부터 자식 컴포넌트로 전달되는 데이터입니다.

1.2 컴포넌트 트리

리액트 애플리케이션은 여러 개의 컴포넌트들로 구성된 트리 형태로 구성됩니다. 이 트리 구조를 통해 데이터가 부모에서 자식으로 흐르는 것을 관리하게 됩니다.

2. Context API 소개

Context API는 리액트에서 컴포넌트 트리의 깊은 곳에 있는 컴포넌트에 데이터를 전달하기 위해 사용됩니다. 여러 레벨을 거치지 않고도 데이터를 공급할 수 있도록 만들어져 있습니다. 이를 통해 속성(props) 전파의 복잡성을 줄일 수 있습니다.

2.1 Context 만들기

Context를 만들기 위해서는 먼저 React의 createContext 함수를 사용해야 합니다.

import React, { createContext, useContext, useState } from 'react';

const MyContext = createContext(); // Context 생성

2.2 Provider와 Consumer

Context의 Provider 컴포넌트를 사용하여 하위 컴포넌트로 데이터를 전달합니다. Provider는 모든 하위 컴포넌트에서 접근할 수 있는 데이터를 제공합니다.

<MyContext.Provider value={/* context value */}>
    {/* children */}
</MyContext.Provider>

2.3 Context 사용하기

하위 컴포넌트에서 Context를 사용하기 위해서는 useContext 훅을 사용하여 데이터를 가져옵니다.

const value = useContext(MyContext); // Context 사용

3. To Do 앱 구조 설정하기

이제 Context API를 활용하여 간단한 To Do 앱을 만들어 보겠습니다. 먼저 기본적인 컴포넌트 구조를 설정합니다.

3.1 기본 컴포넌트 구조

To Do 앱은 다음과 같은 컴포넌트로 구성됩니다.

  • App: 전체 앱을 감싸는 컴포넌트
  • TodoProvider: To Do 리스트의 상태를 관리하는 Provider 컴포넌트
  • TodoList: To Do 항목 리스트를 렌더링하는 컴포넌트
  • TodoItem: 개별 To Do 항목을 렌더링하는 컴포넌트
  • AddTodo: 새로운 To Do 항목을 추가하는 컴포넌트

3.2 앱 코드 작성하기

먼저, TodoProvider 컴포넌트를 작성하여 To Do 리스트의 상태를 관리합니다.

const TodoProvider = ({ children }) => {
    const [todos, setTodos] = useState([]);

    const addTodo = (todo) => {
        setTodos([...todos, todo]);
    };

    const removeTodo = (id) => {
        setTodos(todos.filter(todo => todo.id !== id));
    };

    return (
        <MyContext.Provider value={{ todos, addTodo, removeTodo }}>
            {children}
        </MyContext.Provider>
    );
};

그리고 TodoListAddTodo 컴포넌트를 각각 작성합니다.

const TodoList = () => {
    const { todos, removeTodo } = useContext(MyContext);

    return (
        <ul>
            {todos.map(todo => (
                <TodoItem key={todo.id} todo={todo} onRemove={removeTodo} />
            ))}</ul>
    );
};

const AddTodo = () => {
    const { addTodo } = useContext(MyContext);
    const [inputValue, setInputValue] = useState('');

    const handleSubmit = (e) => {
        e.preventDefault();
        if (!inputValue) return;
        
        addTodo({ id: Date.now(), text: inputValue });
        setInputValue('');
    };

    return (
        <form onSubmit={handleSubmit}>
            <input 
                type="text" 
                value={inputValue} 
                onChange={(e) => setInputValue(e.target.value)} 
                placeholder="새 할 일 입력" 
            />
            <button type="submit">추가하기</button>
        </form>
    );
};

3.3 최종 앱 구조

최종적으로 App 컴포넌트에서 TodoProvider를 사용하여 다른 컴포넌트를 감싸줍니다.

const App = () => {
    return (
        <TodoProvider>
            <h1>할 일 리스트</h1>
            <AddTodo />
            <TodoList />
        </TodoProvider>
    );
};

4. 상태 관리 및 리팩토링

상태 관리는 리액트 애플리케이션에서 중요한 부분입니다. 이를 통해 나중에 데이터의 흐름과 연관성을 더욱 명확하게 할 수 있습니다. Context API를 사용하면 하위 컴포넌트에서 상태를 직접 접근할 수 있어 더욱 효율적으로 관리할 수 있습니다.

4.1 상태 관리 패턴

상태 관리를 위해 여러 가지 패턴을 사용할 수 있습니다. Context API와 함께 사용하는 경우, 컴포넌트가 서브스크라이브 하도록 설계해야 합니다. 이를 통해 재렌더링을 최소화할 수 있습니다.

4.2 리팩토링 예시

리팩토링을 통해 추가적인 기능을 안전하게 구현할 수 있습니다. 예를 들어, To Do 항목의 완료 여부를 처리하는 로직을 추가해 보겠습니다.

const toggleTodo = (id) => {
    setTodos(todos.map(todo => todo.id === id ? { ...todo, completed: !todo.completed } : todo));
};

4.3 완료된 To Do 항목 시각화하기

완료된 To Do 항목을 시각적으로 나타내기 위해 TodoItem 컴포넌트를 수정합니다.

const TodoItem = ({ todo, onRemove }) => {
    return (
        <li style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
            {todo.text}
            <button onClick={() => onRemove(todo.id)}>삭제</button>
        </li>
    );
};

5. 결론

이번 강좌에서는 리액트의 Context API를 활용하여 컴포넌트 트리에 데이터를 공급하고 To Do 애플리케이션을 리팩토링하는 방법에 대해 배웠습니다. Context는 컴포넌트 간의 데이터 공유를 간편하게 하여 애플리케이션의 구조를 보다 깔끔하게 만들어 줍니다.

리액트를 활용한 상태 관리와 데이터 흐름의 이해는 앞으로 복잡한 애플리케이션을 구축하는 데 큰 도움이 될 것입니다. 이제 여러분도 직접 Context API를 활용하여 다양한 애플리케이션을 만들어 보시기를 권장합니다. 감사합니다!

리액트 강좌: 컴포넌트 트리에 데이터 공급하기, Context

리액트는 컴포넌트를 기반으로 한 사용자 인터페이스(UI)를 구축하는 데 사용되는 JavaScript 라이브러리입니다. 이 강좌에서는 React의 Context API를 활용하여 컴포넌트 트리에 데이터를 공급하는 방법에 대해 깊이 있게 다뤄보겠습니다. Context는 리액트의 강력한 기능 중 하나로, 컴포넌트 간에 데이터를 효율적으로 전달할 수 있도록 도와줍니다.

1. Context API란?

Context API는 리액트에서 데이터가 필요 없는 컴포넌트에게도 데이터를 전달할 수 있게 하는 도구입니다. 기본적으로 props drilling(프롭스를 아래로 전달하는 과정)을 피하는 데에 유용합니다. Context를 사용하면 상위 컴포넌트에서 하위 컴포넌트로 직접적으로 props를 전달할 필요 없이 데이터를 전달할 수 있습니다.

Context는 주로 전역 상태관리나 다수의 하위 요소에 필요한 데이터를 공유할 때 유용합니다. 예를 들어, 사용자 인증 정보, UI 언어 설정, 테마 정보 등을 Context를 사용하여 관리할 수 있습니다.

2. Context API의 구성 요소

Context API는 다음의 주요 구성 요소로 이루어져 있습니다:

  • Context 생성하기: React.createContext() 함수를 사용하여 Context를 생성합니다.
  • Provider 컴포넌트: Context의 Provider 컴포넌트를 사용하여 하위 컴포넌트에 데이터를 공급합니다.
  • Consumer 컴포넌트: 하위 컴포넌트에서 데이터를 구독하기 위한 Consumer 컴포넌트입니다. 이 기술은 render props 패턴을 사용합니다.
  • Hooks: useContext 훅을 사용하여 함수형 컴포넌트에서 Context를 사용할 수 있습니다.

3. Context의 생성 및 기본 사용법

Context를 생성하는 방법을 첫 번째로 살펴보겠습니다. 다음 예제를 통해 간단한 Context를 만들어 사용할 수 있는 방법을 설명합니다:


import React, { createContext, useContext, useState } from 'react';

// 3.1. Context 생성
const MyContext = createContext();

// 3.2. Provider 컴포넌트 생성
const MyProvider = ({ children }) => {
    const [value, setValue] = useState('안녕하세요, 리액트!');

    return (
        
            {children}
        
    );
};

// 3.3. Consumer 사용 예시
const MyComponent = () => {
    const { value } = useContext(MyContext);
    return 

{value}

; }; // 3.4. App 컴포넌트 const App = () => ( );

이 예제에서 MyContext를 생성하고, MyProvider를 통해 하위 컴포넌트에게 데이터를 공급하고 있습니다. MyComponent에서는 useContext 훅을 사용하여 Context의 값을 가져옵니다.

4. 리액트 Context의 고급 사용법

Context API를 사용할 때는 기본적인 사용법 외에도 여러 가지 고려해야 될 사항들이 있습니다. 이 섹션에서는 Context를 더 효과적으로 사용하는 여러 전략들에 대해 설명합니다.

4.1. 다중 Context 사용하기

하나의 어플리케이션에서 여러 개의 Context를 사용하는 것이 가능합니다. 다양한 데이터를 각각의 Context로 분리하면 코드가 간결해지며 유지보수성이 높아집니다. 예를 들어, 사용자 설정과 테마 설정, 언어 설정을 각기 다른 Context로 관리할 수 있습니다.


const ThemeContext = createContext();
const LanguageContext = createContext();
            

4.2. Context의 성능 최적화

Context를 사용할 때는 성능이 저하될 수 있습니다. Context에 변경이 생기면 하위 컴포넌트가 모두 다시 렌더링됩니다. 이를 방지하기 위해 더 세분화된 Context로 나누거나, Memoization을 활용하는 방법이 있습니다.


const MyComponent = React.memo(() => {
    const { value } = useContext(MyContext);
    return 

{value}

; });

4.3. Context와 Redux 비교

Context API와 Redux는 모두 전역 상태 관리를 위한 방법입니다. 하지만 Redux는 복잡한 상태 관리를 위한 패턴을 제시하고, 미들웨어와 같은 추가적인 기능을 제공합니다. 간단한 상태 관리에는 Context API가 적합하지만, 애플리케이션이 복잡해질수록 Redux를 고려하는 것이 좋습니다.

5. 리액트 실습 예제

이제 실습을 통해 Context API를 활용해보겠습니다. 아래는 사용자 인증 상태를 관리하는 간단한 예제입니다.


const AuthContext = createContext();

const AuthProvider = ({ children }) => {
    const [isAuthenticated, setIsAuthenticated] = useState(false);

    const login = () => setIsAuthenticated(true);
    const logout = () => setIsAuthenticated(false);

    return (
        
            {children}
        
    );
};

const LoginButton = () => {
    const { login } = useContext(AuthContext);
    return ;
};

const LogoutButton = () => {
    const { logout } = useContext(AuthContext);
    return ;
};

const AuthStatus = () => {
    const { isAuthenticated } = useContext(AuthContext);
    return 

{isAuthenticated ? '로그인 상태입니다' : '로그인 해주세요'}

; }; const App = () => ( );

위의 예제에서는 AuthContext를 만들어 사용자 인증 상태를 관리하고, 관련된 컴포넌트들이 Context를 통해 로그인 및 로그아웃 기능을 제공합니다.

6. 결론

Context API는 리액트에서 컴포넌트 간 데이터를 효율적으로 전달할 수 있게 해주는 강력한 도구입니다. 간단한 데이터 전송부터 복잡한 상태 관리까지 다양한 시나리오에서 활용할 수 있습니다. 성능 문제를 고려하여 적절하게 사용한다면 개발 효율을 크게 증대시킬 수 있습니다. 이번 강좌가 리액트 개발에 도움이 되었기를 바랍니다.

리액트 강좌: 카운터앱 예제 만들기

리액트(React)는 현대 웹 개발에서 가장 인기 있는 JavaScript 라이브러리 중 하나입니다. 이 강좌에서는 리액트를 사용하여 카운터앱을 만드는 방법을 배웁니다. 카운터앱은 매우 간단한 프로젝트이지만, 리액트의 기본 개념을 이해하고 활용하는 데 큰 도움이 됩니다. 본 강좌의 목표는 다음과 같습니다:

  • 리액트의 기본 개념 이해하기
  • 리액트 컴포넌트 생성 및 관리하기
  • 상태(state)와 속성(props) 이해하기
  • 이벤트 처리 및 상태 업데이트 구현하기
  • 리액트를 통해 애플리케이션 개발하기

1. 프로젝트 준비하기

본 카운터앱 프로젝트를 시작하기 전에, 필요한 준비물을 정리해 보겠습니다. 개발에 필요한 기본적인 환경을 마련해야 합니다.

1.1. 개발 환경 설정

리액트를 사용하기 위해서는 먼저 Node.js와 npm(Node Package Manager)를 설치해야 합니다. Node.js는 JavaScript 실행 환경을 제공하고, npm은 패키지 관리를 위한 도구입니다.

  1. Node.js 다운로드: Node.js 공식 웹사이트에서 설치 프로그램을 다운로드하여 설치합니다.
  2. npm 확인: 설치가 완료된 후, 다음 명령어를 통해 설치된 Node.js와 npm의 버전을 확인합니다.
  3. node -v
    npm -v

1.2. 새로운 리액트 프로젝트 생성

리액트 프로젝트를 생성하기 위해, Create React App라는 도구를 사용합니다. 이는 리액트 앱의 초기 설정을 자동으로 구성해줍니다. 다음 명령어를 사용하여 새로운 리액트 프로젝트를 생성합니다:

npx create-react-app counter-app

위 명령어를 입력하면 counter-app이라는 이름의 폴더가 생성되며, 리액트 애플리케이션의 기본 템플릿이 설정됩니다. 완료 후 해당 폴더로 이동합니다:

cd counter-app

1.3. 개발 서버 실행

프로젝트 폴더로 이동한 후, 다음 명령어로 개발 서버를 실행할 수 있습니다:

npm start

이 명령어를 입력하면 기본 웹 브라우저에서 `http://localhost:3000` 주소로 리액트 앱이 열립니다. 초기 화면을 통해 리액트가 정상적으로 설치되었는지 확인합니다.

2. 카운터앱 설계

이제 카운터앱의 기능과 UI에 대해 간단히 설계해 보겠습니다. 기본적으로 이 앱은 사용자가 버튼을 클릭하여 카운트를 증가시키거나 감소시킬 수 있는 기능을 제공합니다.

2.1. 주요 기능

  • 카운트를 증가시키는 버튼
  • 카운트를 감소시키는 버튼
  • 현재 카운트를 표시하는 텍스트
  • 초기 카운트 값을 설정할 수 있는 기능

2.2. UI 설계

카운터앱의 UI는 간단합니다. 기본적으로 버튼 2개와 상태를 표시할 텍스트가 포함됩니다. 기본적인 HTML 구조를 통해 컴포넌트를 설계합니다.

3. 카운터앱 구현

이제 실제로 카운터앱을 구현해 보겠습니다. src 폴더 내에 Counter.js 파일을 생성하고 컴포넌트를 작성합니다.

3.1. Counter 컴포넌트 생성

import React, { useState } from 'react';

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

    const increment = () => {
        setCount(count + 1);
    };

    const decrement = () => {
        setCount(count - 1);
    };

    return (
        

현재 카운트: {count}

); }; export default Counter;

위의 코드는 간단한 카운터 기능을 포함한 리액트 컴포넌트입니다. useState 훅을 사용하여 카운트 상태를 관리합니다.

3.2. App.js에 Counter 컴포넌트 추가

이제 App.js 파일을 열어 Counter 컴포넌트를 추가합니다. 해당 파일을 다음과 같이 수정합니다:

import React from 'react';
import Counter from './Counter';

function App() {
    return (
        
); } export default App;

4. 스타일링 추가하기

카운터앱에 일부 스타일을 추가하여 더 보기 좋게 만들어 보겠습니다. 미리 정의된 CSS 파일을 사용하거나 스타일을 인라인으로 적용할 수 있습니다. 여기서는 CSS 파일을 사용하여 스타일링하겠습니다.

4.1. styles.css 파일 생성

body {
    font-family: Arial, sans-serif;
    text-align: center;
}

button {
    margin: 10px;
    padding: 10px 15px;
    font-size: 16px;
}

4.2. 스타일 적용하기

이제 스타일을 App.js에 불러와서 적용할 수 있습니다:

import React from 'react';
import './styles.css'; // 새로운 CSS 파일을 import
import Counter from './Counter';

function App() {
    return (
        
); } export default App;

5. 추가 기능 구현

이제 기본 카운터 앱이 완성되었습니다. 다음으로는 사용자가 초기 카운트 값을 설정할 수 있는 기능을 추가해 보겠습니다.

5.1. 초기 카운트 설정 기능

const Counter = () => {
    const [count, setCount] = useState(0);
    const [inputValue, setInputValue] = useState('');

    const increment = () => {
        setCount(count + 1);
    };

    const decrement = () => {
        setCount(count - 1);
    };

    const setInitialCount = (e) => {
        e.preventDefault();
        setCount(Number(inputValue));
        setInputValue('');
    };

    return (
        

현재 카운트: {count}

setInputValue(e.target.value)} />
); };

위의 코드에서 inputValue 상태를 추가하여 사용자가 숫자를 입력할 수 있도록 했습니다. 초기 값을 설정하는 버튼을 추가했고, 클릭 시 해당 값을 카운트에 적용합니다.

6. 마무리 및 배포

카운터앱의 구현을 마쳤습니다. 이제 애플리케이션을 배포할 준비를 합니다. 기본적인 방법은 두 가지가 있습니다: GitHub Pages 및 Vercel.

6.1. GitHub Pages 배포

  1. 프로젝트를 GitHub에 푸시합니다.
  2. 다음 명령어를 통해 프로젝트를 빌드합니다:
  3. npm run build
  4. 생성된 build 폴더를 GitHub Pages에 호스팅합니다.

6.2. Vercel 배포

  1. Vercel에 가입한 후, GitHub 레포지토리를 연결합니다.
  2. Vercel이 자동적으로 프로젝트를 배포합니다.

결론

이 강좌를 통해 리액트의 기본 개념과 카운터앱을 구현해 보았습니다. 이 과정을 통해 리액트의 상태 관리, 컴포넌트 생성 및 이벤트 처리 방법을 이해하는 데 도움이 되었기를 바랍니다. 이후 더 복잡한 프로젝트에 도전하며 리액트 실력을 키워보세요!

이 글이 유용하셨다면, 블로그를 구독하고 다른 강좌도 확인해보세요!

리액트 강좌: 컴포넌트

리액트는 현대적인 사용자 인터페이스를 구축하기 위해 사용되는 가장 인기 있는 JavaScript 라이브러리 중 하나입니다. 리액트는 재사용 가능한 UI 컴포넌트를 만들도록 설계되어 있어, 대규모 애플리케이션에서 복잡한 구조를 관리하고 유지하는 데 매우 유용합니다. 이 글에서는 리액트 컴포넌트에 대한 심층적인 이해를 돕기 위해 컴포넌트의 개념, 종류, 생성 방법 및 실전 예제에 대해 상세히 설명하겠습니다.

1. 컴포넌트란 무엇인가?

컴포넌트는 UI의 구성 요소로, 독립적으로 재사용 가능한 코드 조각입니다. 각 컴포넌트는 독립적인 상태와 생명 주기를 가질 수 있으며, 다른 컴포넌트와 조합하여 복잡한 UI를 구성할 수 있습니다. 컴포넌트를 사용하면 코드의 가독성을 높이고, 재사용성을 극대화할 수 있습니다.

1.1 컴포넌트의 장점

  • 재사용성: 이미 작성된 컴포넌트를 다른 프로젝트 또는 동일한 프로젝트 내에서 손쉽게 재사용할 수 있습니다.
  • 모듈화: 각각의 컴포넌트는 독립적으로 기능하므로, 코드의 유지보수가 쉬워집니다.
  • 테스트 용이성: 각 컴포넌트가 독립적으로 동작하기 때문에, 개별적으로 테스트하기도 용이합니다.

2. 컴포넌트의 종류

리액트에서 컴포넌트는 주로 두 가지 유형으로 나눌 수 있습니다: 클래스형 컴포넌트와 함수형 컴포넌트입니다.

2.1 클래스형 컴포넌트

클래스형 컴포넌트는 ES6 class 구문을 사용하여 정의됩니다. 이들은 상태(state)를 가질 수 있으며, 라이프사이클 메서드를 활용하여 컴포넌트의 생명 주기를 제어할 수 있습니다.

import React, { Component } from 'react';

class MyClassComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

export default MyClassComponent;

2.2 함수형 컴포넌트

함수형 컴포넌트는 간단한 JavaScript 함수로 정의됩니다. 리액트 Hooks가 도입된 후, 함수형 컴포넌트에서도 상태를 관리할 수 있게 되었습니다.

import React, { useState } from 'react';

const MyFunctionalComponent = () => {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
};

export default MyFunctionalComponent;

3. 컴포넌트 생성하기

리액트 컴포넌트를 생성하는 방법은 어려운 과정이 아닙니다. 아래에서는 클래스형 및 함수형 컴포넌트의 기본적인 예제를 통해 컴포넌트를 만드는 과정을 살펴보겠습니다.

3.1 클래스형 컴포넌트 만들기

우리는 ‘Counter’라는 이름의 카운터 컴포넌트를 만들 것입니다.

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  }

  decrement = () => {
    this.setState({ count: this.state.count - 1 });
  }

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
        <button onClick={this.decrement}>Decrement</button>
      </div>
    );
  }
}

export default Counter;

3.2 함수형 컴포넌트 만들기

아래는 같은 기능을 가진 ‘Counter’라는 함수형 컴포넌트입니다.

import React, { useState } from 'react';

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

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
};

export default Counter;

4. Props와 State

컴포넌트는 비슷해 보일 수 있으나, 각 컴포넌트는 데이터를 다루는 방식에서 많은 차이를 보입니다. 이 섹션에서는 props와 state에 대해 자세히 설명하겠습니다.

4.1 Props(속성)

Props는 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달하는 방법입니다. Props는 읽기 전용이므로 컴포넌트 내부에서 직접 수정할 수 없습니다. 부모 컴포넌트에서 전달된 데이터를 바탕으로 컴포넌트의 렌더링 결과가 변하게 됩니다.

const Welcome = (props) => {
  return <h1>Hello, {props.name}</h1>;
};

const App = () => {
  return (
    <div>
      <Welcome name="Alice" />
      <Welcome name="Bob" />
    </div>
  );
};

4.2 State(상태)

State는 컴포넌트 내에서 관리되는 데이터로, 사용자가 입력한 값이나 API 호출의 결과와 같은 동적인 데이터를 표현합니다. State가 업데이트되면 리액트는 해당 컴포넌트를 다시 렌더링하여 UI를 갱신합니다.

import React, { useState } from 'react';

const Toggle = () => {
  const [isOn, setIsOn] = useState(false);

  const toggleSwitch = () => {
    setIsOn(!isOn);
  };

  return (
    <div>
      <p>Switch is {isOn ? 'On' : 'Off'}</p>
      <button onClick={toggleSwitch}>Toggle</button>
    </div>
  );
};

5. 컴포넌트 생명주기

리액트 컴포넌트의 생명주기는 마운트, 업데이트 및 언마운트의 세 가지 주요 단계로 나뉩니다. 각 단계에서 호출되는 특정 라이프사이클 메서드가 있습니다.

5.1 마운트(Mounting)

컴포넌트가 DOM에 추가될 때 호출되는 메서드입니다. 대표적으로 constructor, componentDidMount가 있습니다.

class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = { data: null };
  }

  componentDidMount() {
    // API 호출 등 초기 작업
  }

  render() {
    return <div>My Component</div>;
  }
}

5.2 업데이트(Updating)

컴포넌트의 props나 state가 변할 때 호출되는 메서드입니다. componentDidUpdate가 대표적입니다.

componentDidUpdate(prevProps, prevState) {
  if (this.state.data !== prevState.data) {
    // 데이터 변경 시 처리
  }
}

5.3 언마운트(Unmounting)

컴포넌트가 DOM에서 제거될 때 호출되는 componentWillUnmount 메서드입니다. 주로 청소 작업을 수행하는 데 사용됩니다.

componentWillUnmount() {
  // 타이머 정리 등
}

6. 고급 컴포넌트 패턴

리액트에서는 고급 컴포넌트 패턴을 통해 복잡한 UI의 구조를 더욱 간단하게 만들 수 있습니다. 다음은 일부 고급 컴포넌트 패턴입니다.

6.1 Higher-Order Components (HOC)

HOC는 컴포넌트를 인자로 받아 다른 컴포넌트를 반환하는 컴포넌트입니다. 이를 통해 코드의 중복을 줄이고 재사용성을 높일 수 있습니다.

const withLogging = (WrappedComponent) => {
  return class extends Component {
    componentDidMount() {
      console.log('Component mounted');
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
};

6.2 Render Props

Render Props 패턴은 컴포넌트에서 함수를 props로 전달하여 렌더링할 내용을 결정하는 패턴입니다. 이를 통해 데이터를 처리하는 로직과 UI를 분리할 수 있습니다.

class DataProvider extends Component {
  render() {
    return this.props.render(data);
  }
}

7. 결론

리액트 컴포넌트는 현대 웹 개발의 핵심 구성 요소로서, 재사용성과 유지보수를 용이하게 만들어 주는 강력한 도구입니다. 이번 강좌를 통해 컴포넌트의 기본 개념, 다양한 종류, 생성 방법 및 고급 패턴에 대해 알아보았습니다. 이러한 지식을 바탕으로 여러분의 리액트 애플리케이션이 한층 더 발전할 수 있기를 바랍니다.

리액트의 컴포넌트에 대한 추가적인 정보를 원하신다면 공식 문서를 참고하시기 바랍니다. 감사합니다!

리액트 강좌: 카운터앱 예제 만들기

리액트(React)는 UI를 만들기 위해 가장 많이 사용되는 JavaScript 라이브러리 중 하나입니다. 이 강좌에서는 리액트를 사용하여 간단한 카운터 앱을 만드는 방법을 알아보겠습니다. 이 앱은 기본적인 상태(state) 관리, 이벤트 처리 및 리액트의 컴포넌트 기반 아키텍처를 활용하여 구성됩니다.

1. 프로젝트 설정

먼저, 리액트 프로젝트를 시작하기 위해 create-react-app을 사용해 보겠습니다. 이 도구는 리액트 앱을 쉽게 설정할 수 있도록 도와줍니다. 아래 명령어를 실행하여 리액트 프로젝트를 생성합니다.

        npx create-react-app counter-app
    

프로젝트가 생성되면 생성된 디렉토리로 이동합니다.

        cd counter-app
    

2. 카운터 컴포넌트 생성하기

이제 카운터 컴포넌트를 만들어 보겠습니다. src 폴더 내에 Counter.js라는 파일을 생성하고 다음 코드를 작성합니다.

        import React, { useState } from 'react';

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

    const increment = () => {
        setCount(count + 1);
    };

    const decrement = () => {
        setCount(count - 1);
    };

    return (
        

카운트: {count}

); }; export default Counter;

3. 카운터 컴포넌트 추가하기

이제 메인 App.js 파일에 이 카운터 컴포넌트를 추가해 보겠습니다. src/App.js 파일을 열고 아래와 같이 수정합니다.

        import React from 'react';
import Counter from './Counter';

function App() {
    return (
        

리액트 카운터 앱

); } export default App;

4. 앱 실행하기

모든 코드 변경이 완료되었으므로, 다음 명령어로 앱을 실행합니다.

        npm start
    

웹 브라우저에서 http://localhost:3000를 열면 기본적인 카운터 앱을 볼 수 있습니다.

5. 기능 추가하기

이제 카운터 앱에 몇 가지 추가 기능을 구현해 보겠습니다. 예를 들어, 카운트를 리셋하는 버튼과 최대값 및 최소값을 설정하는 기능을 추가할 수 있습니다.

5.1. 리셋 버튼 추가하기

카운터 컴포넌트에 리셋 버튼을 추가해 보겠습니다. 아래와 같이 코드를 수정합니다.

        const reset = () => {
        setCount(0);
    };

    return (
        

카운트: {count}

);

5.2. 최대 및 최소값 제한하기

이제 카운트가 최대값과 최소값을 초과하지 않도록 제한해 보겠습니다. 아래와 같이 코드를 수정합니다.

        const MAX_COUNT = 10;
const MIN_COUNT = 0;

const increment = () => {
    if (count < MAX_COUNT) {
        setCount(count + 1);
    }
};

const decrement = () => {
    if (count > MIN_COUNT) {
        setCount(count - 1);
    }
};
    

6. 상태 관리의 효율성

리액트에서 상태 관리 방법은 여러 가지가 있습니다. 이 앱처럼 간단한 경우에는 useState 훅이 적합하지만, 애플리케이션이 커지거나 상태 관리가 복잡해지면 Context APIRedux와 같은 외부 상태 관리 라이브러리를 고려해 볼 수 있습니다.

7. 결론

이번 강좌에서는 리액트를 사용하여 간단한 카운터 앱을 만들어 보았습니다. 기본적인 상태 관리, 이벤트 처리, 그리고 컴포넌트 기반 아키텍처에 대해 알아보았습니다. 이와 같은 기초를 바탕으로, 더 복잡한 애플리케이션을 개발할 수 있는 기반이 마련되었습니다.

8. 다음 단계

더 많은 기능을 구현하거나 디자인을 개선하여 나만의 카운터 앱을 확장해 보세요. 리액트의 다양한 기능을 활용하면 훨씬 더 복잡하고 매력적인 애플리케이션을 개발할 수 있습니다. 다음 강좌에서는 리액트 라우터를 사용하여 다중 페이지 애플리케이션을 만드는 방법에 대해 알아보겠습니다.

이 강좌가 도움이 되길 바라며, 질문이나 피드백이 있으시면 댓글로 남겨주세요!