React 기본 개념 이해하기, JSX의 개념과 HTML과의 차이점

React는 사용자 인터페이스(UI)를 구축하기 위해 Facebook에서 개발한 JavaScript 라이브러리입니다.
현대의 웹 애플리케이션은 복잡하고 상호작용이 많아짐에 따라, 효율적이고 빠른 UI 개발을 위해
컴포넌트 기반 접근 방식이 필요해졌습니다. React는 이러한 컴포넌트 기반 아키텍처를 제공하여 코드의
재사용성과 관리의 용이성을 향상시키는데 중점을 두고 있습니다.

1. 컴포넌트 기반 구조

React의 핵심 개념 중 하나는 ‘컴포넌트’입니다. 컴포넌트는 UI의 독립적이고 재사용 가능한 조각으로,
각 컴포넌트는 자신의 상태(state)와 속성(props)을 가질 수 있습니다. 이를 통해 UI를 작은 단위로
나누어 관리할 수 있으므로, 대규모 애플리케이션의 복잡성을 줄일 수 있습니다.

컴포넌트는 기본적으로 두 가지 유형으로 나눌 수 있습니다:

  • 클래스 컴포넌트: ES6 클래스 문법을 사용하여 정의된 컴포넌트로, 상태를 가질 수 있습니다.
  • 함수형 컴포넌트: 함수를 사용하여 정의된 컴포넌트로, React 16.8부터는 훅(Hooks)을 통해 상태와 생명주기 기능을 사용할 수 있습니다.

아래는 간단한 React 컴포넌트 예제입니다:

            
                import React from 'react';

                class Greeting extends React.Component {{
                    render() {{
                        return <h1>Hello, {this.props.name}!</h1>;
                    }}
                }}

                export default Greeting;
            
        

2. 상태와 속성

React에서는 두 가지 주요 개념인 상태(state)와 속성(props)이 있습니다. 두 개념은 컴포넌트의
동작을 조절하는데 중요한 역할을 합니다.

상태(state)

컴포넌트의 상태는 컴포넌트 내부에서 관리되는 데이터입니다. 상태가 변경되면 컴포넌트가 다시 렌더링되어 UI가
업데이트됩니다. 상태는 주로 클래스 컴포넌트에서는 this.statesetState 메서드를
사용하여 관리합니다. 함수형 컴포넌트에서는 useState 훅을 사용하여 상태를 관리합니다.

            
                import React, { useState } from 'react';

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

                    return (
                        <div>
                            <p>Current Count: {count}</p>
                            <button onClick={() => setCount(count + 1)}>Increase</button>
                        </div>
                    );
                }};

                export default Counter;
            
        

속성(props)

속성은 컴포넌트 외부에서 전달된 데이터이며, 컴포넌트의 속성을 통해 부모 컴포넌트에서 자식 컴포넌트로
데이터를 전달할 수 있습니다. 속성은 읽기 전용이며, 자식 컴포넌트에서는 수정할 수 없습니다.

            
                import React from 'react';

                const UserProfile = (props) => {{
                    return <div>
                        <h2>Name: {props.name}</h2>
                        <p>Age: {props.age}</p>
                    </div>
                }}

                const App = () => {{
                    return <UserProfile name="John Doe" age={30} />;
                }};

                export default App;
            
        

3. JSX의 개념

JSX는 JavaScript XML의 약어로, React에서 UI를 정의하기 위해 사용하는 문법입니다.
JSX는 JavaScript 코드 안에서 HTML과 유사한 구조로 UI를 작성할 수 있게 해줍니다. JSX는
JavaScript ES6 문법을 활용하여 다양한 기능을 제공하며, React가 이를 이해하고 DOM에
렌더링할 수 있습니다. 단순한 텍스트로서는 코드를 제공하지 않기 때문에, HTML이나 XML에서는
문법 오류를 많이 발생할 수 있습니다.

JSX의 사용 예시는 다음과 같습니다:

            
                const element = <h1>Hello, World!</h1>;
            
        

위의 코드는 React.createElement를 호출하는 것과 동일합니다. 변환된 결과는
다음과 같은 형태가 됩니다.

            
                const element = React.createElement('h1', null, 'Hello, World!');
            
        

4. JSX와 HTML의 차이점

JSX와 HTML은 유사하지만 몇 가지 주요 차이점이 있습니다. JSX는 JavaScript의 일부이므로,
JavaScript 코드처럼 중괄호({})를 사용하여 동적으로 데이터를 삽입할 수 있습니다.
또한, HTML에서 사용하는 속성명과 JSX에서 사용하는 속성명이 다소 다르게 적용됩니다.

주요 차이점

  • 클래스 속성: HTML에서는 class로 지정하지만, JSX에서는 className을 사용해야 합니다.
  • for 속성: HTML의 for 속성은 JSX에서 htmlFor로 사용됩니다.
  • Inline 스타일링: HTML의 스타일 속성은 문자열로 주어지지만, JSX에서는 객체 형태로 주어집니다.
  • JavaScript 표현: JSX에서는 중괄호({})를 사용하여 JavaScript 표현식을 포함할 수 있습니다.

아래는 JSX와 HTML의 주요 차이점을 보여주는 예시입니다:

            
               // JSX 예시
               const element = <div className="container">
                    <label htmlFor="username">Username</label>
                    <input type="text" id="username" />
                </div>;
                
                / / 비슷한 HTML
                <div class="container">
                    <label for="username">Username</label>
                    <input type="text" id="username" />
                </div>
            
        

5. 결론

React는 현대의 웹 애플리케이션 개발에 매우 유용한 도구이며, 컴포넌트 기반의 구조와
상태 및 속성을 이해하는 것은 효과적인 개발을 위한 핵심 요소입니다. JSX는 UI를 더 간결하고
명확하게 표현할 수 있게 해줍니다. HTML과 JSX의 차이점을 이해하고 활용함으로써, 보다
효율적인 React 애플리케이션을 구축할 수 있습니다.

앞으로 더 깊이 있는 주제, 예를 들어 React Router, Redux, Context API 등을 다루어 볼 계획입니다.
계속해서 배우고 함께 성장해 나가길 기대합니다.

지도에서 위치 검색 및 주소 표시 기능 구현, 검색 결과와 연동하여 지도 위치 이동

이 글에서는 리액트 프론트앤드 개발을 통해 지도에서 위치 검색 및 주소 표시 기능을 구현하는 방법에 대해 자세히 알아보겠습니다. 이 과정에서는 다양한 기술 스택을 사용하여 사용자에게 더욱 편리하고 직관적인 지도 경험을 제공할 것입니다.

1. 프로젝트 설정

먼저 리액트 프로젝트를 설정해야 합니다. Create React App을 사용하여 신규 리액트 프로젝트를 생성합니다.

            npx create-react-app react-map-search
        

설치가 완료되면 프로젝트 디렉토리로 이동합니다.

            cd react-map-search
        

2. 지도 API 선택 및 설치

여기서는 Google Maps API를 사용하여 지도를 표시하고, 위치 검색 기능을 구현해 보겠습니다. 시작하기 전에 Google Cloud Console에서 API 키를 발급받아야 합니다.

API 키를 발급받은 후, 필요한 라이브러리를 설치합니다.

            npm install @react-google-maps/api
        

3. 기본 지도의 설정

이제 기본적인 지도를 설정할 준비가 되었습니다. 먼저 App.js 파일을 열고 다음과 같이 수정합니다.

            
                import { GoogleMap, LoadScript } from '@react-google-maps/api';
                const mapContainerStyle = {
                    height: "400px",
                    width: "800px"
                };
                const center = {
                    lat: -3.745,
                    lng: -738
                };
                
                function App() {
                    return (
                        
                            
                            
                        
                    );
                }
                export default App;
            
        

4. 위치 검색 기능 구현

지도에서 위치 검색을 가능하게 하기 위해 입력 필드를 추가하고 사용자가 입력한 주소를 기반으로 위치를 검색하는 기능을 구현합니다.

            
                import { useState } from 'react';
                import { GoogleMap, LoadScript, Marker } from '@react-google-maps/api';
                
                function App() {
                    const [location, setLocation] = useState(center);
                    const [address, setAddress] = useState("");

                    const handleSearch = () => {
                        const geocoder = new window.google.maps.Geocoder();
                        geocoder.geocode({ address: address }, (results, status) => {
                            if (status === "OK") {
                                setLocation({
                                    lat: results[0].geometry.location.lat(),
                                    lng: results[0].geometry.location.lng()
                                });
                            } else {
                                alert("주소를 찾을 수 없습니다.");
                            }
                        });
                    };

                    return (
                        
                             setAddress(e.target.value)}
                                placeholder="주소를 입력하세요"
                            />
                            
                            
                                
                            
                        
                    );
                }
            
        

위의 코드는 입력한 주소를 기반으로 지도를 업데이트하고 해당 주소에 마커를 표시하는 기능을 구현합니다. 사용자가 주소를 입력하고 검색 버튼을 클릭하면, Google Geocoding API를 통해 주소를 위도와 경도로 변환합니다.

5. 사용자 인터페이스 개선

사용자 편의를 위해 입력 필드와 버튼을 스타일링하여 더 나은 사용자 경험을 제공합니다.

            
                const inputStyle = {
                    padding: "10px",
                    marginBottom: "10px",
                    width: "300px"
                };

                // App 컴포넌트 안에서
                return (
                    
setAddress(e.target.value)} placeholder="주소를 입력하세요" /> // ... 나머지 코드
);

이제 사용자가 입력한 주소를 보다 잘 볼 수 있도록 입력창에 스타일을 추가했습니다.

6. 에러 처리 및 사용자 피드백

검색을 수행할 때 발생할 수 있는 여러 오류를 처리하고 사용자에게 피드백을 제공하는 것이 중요합니다. 예를 들어, 주소가 잘못된 경우에 대한 처리를 추가하겠습니다.

            
                const handleSearch = () => {
                    // ... 기존 코드

                    geocoder.geocode({ address: address }, (results, status) => {
                        if (status === "OK") {
                            // 위치 업데이트
                        } else {
                            alert("주소를 찾을 수 없습니다: " + status);
                        }
                    });
                };
            
        

7. 여러 마커와 경로 표시

여러 위치를 검색할 수 있도록 다수의 마커를 지도에 표시하는 기능을 추가합니다. 여러 주소를 검색한 후, 이들이 모두 지도에 표시될 수 있도록 하겠습니다.

            
                const [markers, setMarkers] = useState([]);

                const handleSearch = () => {
                    // ... 기존 코드
                    setMarkers([...markers, { lat: location.lat, lng: location.lng }]);
                };

                return (
                    
                        {markers.map((marker, index) => (
                            
                        ))}
                    
                );
            
        

8. 최종 점검 및 배포

모든 기능이 구현되면, 잘 동작하는지 확인한 후 배포 준비를 합니다. 사용자에게 배포할 수 있도록 빌드합니다.

            npm run build
        

결론

이번 강좌에서는 리액트를 활용하여 지도에서 위치를 검색하고, 주소를 표시하는 기능을 구현하는 방법에 대해 알아보았습니다. 이를 통해 사용자에게 보다 나은 경험을 제공하고, UI의 가능성을 확장할 수 있습니다. 더 나아가, 사용자 맞춤형 기능이나 추가적인 API를 연계하여 더욱 발전된 웹 어플리케이션을 만들 수 있습니다.

리액트로 풀스택 애플리케이션 구축하기, 프론트엔드와 백엔드 통신 설정

오늘날의 웹 개발에서는 프론트엔드와 백엔드 개발을 통합하여 풀스택 애플리케이션을 만드는 것이 매우 중요합니다.
리액트(React)는 사용자 인터페이스를 구축하는 데 있어 가장 인기 있는 라이브러리 중 하나로,
Node.js와 Express.js와 같은 백엔드 기술과 함께 사용하여 강력한 웹 애플리케이션을 만들 수 있습니다.
이 글에서는 리액트를 사용하여 풀스택 애플리케이션을 구축하는 방법과 프론트엔드와 백엔드 간의 데이터 통신을 설정하는 방법에 대해 안내합니다.

개요

풀스택 애플리케이션이란 프론트엔드와 백엔드를 모두 포함하는 애플리케이션을 의미합니다.
프론트엔드는 사용자가 상호작용하는 부분이고, 백엔드는 데이터를 처리하고 저장하는 서버 측 부분입니다.
이 두 부분 간의 원활한 통신이 풀스택 애플리케이션의 핵심입니다.
본 강좌에서는 리액트 프론트엔드와 Node.js/Express 백엔드를 연동하는 방법을 학습하게 됩니다.

사전 준비 사항

강좌에 앞서 필요한 환경을 설정해야 합니다. 다음과 같은 도구가 필요합니다:

  • Node.js: JavaScript 런타임(버전 14 이상 권장)
  • npm 또는 yarn: 패키지 매니저
  • 리액트 앱 생성기(create-react-app)
  • Postman: API 테스트를 위한 툴(선택 사항)

1. 리액트 애플리케이션 설정하기

리액트 애플리케이션을 생성하기 위해 create-react-app을 사용합니다.
다음 명령어를 실행하여 새 리액트 애플리케이션을 만듭니다:

npx create-react-app my-fullstack-app

애플리케이션 디렉토리로 이동합니다:

cd my-fullstack-app

애플리케이션이 생성되면, 기본 리액트 구조가 생성됩니다.
이제 개발 서버를 시작하여 애플리케이션이 제대로 작동하는지 확인합니다:

npm start

2. 백엔드 설정하기

리액트 프론트엔드와 통신할 Node.js 백엔드를 만듭니다.
새 폴더를 생성하고 그 안에 백엔드 코드를 작성합니다. 아래 명령어로 백엔드를 만들기 위해 새로운 디렉토리를 생성합니다:

mkdir backend && cd backend

이제 Node.js 프로젝트를 초기화합니다:

npm init -y

Express.js를 설치합니다:

npm install express

3. Express 서버 설정

Express 서버를 설정하고 기본 API 엔드포인트를 추가합니다.
express를 사용하여 `server.js` 파일을 생성하십시오:

touch server.js

`server.js` 파일에 다음 코드를 추가합니다:


const express = require('express');
const app = express();
const PORT = process.env.PORT || 5000;

app.use(express.json());

app.get('/api/data', (req, res) => {
    res.json({ message: 'Hello from backend!' });
});

app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
});
        

서버를 시작하기 위해 다음 명령어를 입력합니다:

node server.js

4. 프론트엔드에서 백엔드 API 호출하기

리액트 애플리케이션에서 axios를 이용하여 API를 호출합니다.
axios를 설치하기 위해 다음 명령어를 실행합니다:

npm install axios

이제 이 라이브러리를 사용하여 백엔드에서 데이터를 가져옵니다.
`src/App.js`를 열고 아래와 같이 코드를 수정합니다:


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

function App() {
    const [data, setData] = useState({});

    useEffect(() => {
        const fetchData = async () => {
            const result = await axios('/api/data');
            setData(result.data);
        };
        fetchData();
    }, []);

    return (
        

{data.message}

); } export default App;

이제 서버를 다시 시작한 후, 리액트 앱에서 API 요청을 확인할 수 있습니다.
개발 서버를 다시 시작하려면 리액트 앱에서 `npm start`를 실행하세요.

5. CORS 설정하기

만약 리액트 앱과 백엔드 서버가 서로 다른 포트에서 실행되고 있을 경우, CORS 정책 문제로 인해 요청이 차단될 수 있습니다.
이를 해결하기 위해 `cors` 패키지를 설치해야 합니다:

npm install cors

그 후, `server.js`에 위 아래 코드를 추가하여 CORS를 활성화합니다:


const cors = require('cors');
app.use(cors());
        

6. 데이터베이스와의 연결

애플리케이션이 실제 데이터와 상호작용할 수 있도록 데이터베이스를 설정합니다.
MongoDB 또는 MySQL과 같은 데이터베이스를 사용할 수 있습니다.
이번 예제에서는 MongoDB를 사용한다고 가정하고, 데이터베이스와 연결하는 방법을 설명하겠습니다.

먼저 MongoDB Atlas에 가입하여 클러스터를 생성한 후,
`mongoose` 패키지를 설치합니다:

npm install mongoose

이후, `server.js`에 다음 코드를 추가하여 MongoDB에 연결합니다:


const mongoose = require('mongoose');
const dbURI = 'YOUR_MONGODB_CONNECTION_STRING';

mongoose.connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => console.log('MongoDB connected'))
    .catch(err => console.error(err));
        

7. 데이터 모델 생성하기

MongoDB의 데이터 구조를 정의하기 위해 모델을 생성합니다.
`models` 폴더를 만들고 `User.js`라는 파일을 생성한 후, 다음 코드를 추가합니다:


const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
    name: String,
    email: String
});

module.exports = mongoose.model('User', UserSchema);
        

8. 데이터 CRUD 작업 구현하기

이제 CRUD(생성, 읽기, 업데이트, 삭제) 작업을 수행하는 API 엔드포인트를 추가합니다.
`server.js`에 다음 코드를 추가합니다:


app.post('/api/users', async (req, res) => {
    const user = new User(req.body);
    await user.save();
    res.status(201).send(user);
});

app.get('/api/users', async (req, res) => {
    const users = await User.find();
    res.send(users);
});
        

이러한 엔드포인트를 통해 프론트엔드에서 데이터를 관리할 수 있습니다.
이제 리액트 프론트엔드에서 사용자 등록과 목록을 표시하기 위한 UI를 구현해야 합니다.

9. 프론트엔드에서 사용자 등록 기능 구현하기

사용자 등록 폼을 구현하기 위해 `src/App.js`를 수정합니다:


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

function App() {
    const [users, setUsers] = useState([]);
    const [name, setName] = useState('');
    const [email, setEmail] = useState('');

    useEffect(() => {
        const fetchUsers = async () => {
            const result = await axios('/api/users');
            setUsers(result.data);
        };
        fetchUsers();
    }, []);

    const handleSubmit = async (e) => {
        e.preventDefault();
        await axios.post('/api/users', { name, email });
        setName(''); 
        setEmail('');
        const result = await axios('/api/users');
        setUsers(result.data);
    };

    return (
        

User Registration

setName(e.target.value)} placeholder="Name" required /> setEmail(e.target.value)} placeholder="Email" required />

User List

    {users.map(user => (
  • {user.name} - {user.email}
  • ))}
); } export default App;

결론

이번 강좌에서는 리액트를 사용하여 풀스택 애플리케이션을 구축하는 방법을 배웠습니다.
프론트엔드와 백엔드 간의 통신 설정, 데이터베이스와의 연결, CRUD 작업을 구현한 사례를 통해
실무에서 필요로 하는 기술을 익힐 수 있었습니다.
이렇게 구축한 애플리케이션은 기본적인 사용자 등록 기능을 제공하지만,
이외에도 다양한 CRUD 기능 및 상태 관리 라이브러리(예: Redux)와 같은 고급 기능을 추가하여 확장할 수 있습니다.

리액트와 Node.js를 이용한 풀스택 개발은 지금도 인기가 많은 분야로,
여러분의 개발 역량을 한층 더 높이는 데 큰 도움이 될 것입니다.

API와 서버와의 통신, JSON 서버나 Mock API로 데이터 연동

현대 웹 개발에서 클라이언트와 서버 간의 통신은 매우 중요한 부분입니다. 특히, 리액트(React)와 같은 프론트엔드 라이브러리를 사용할 때, API를 통한 데이터 요청과 처리는 매우 일반적인 작업이 됩니다. 이 글에서는 리액트를 사용하여 JSON 서버나 Mock API와 통신하는 방법을 깊이 있게 다루겠습니다.

1. API란 무엇인가?

API(응용 프로그램 프로그래밍 인터페이스, Application Programming Interface)는 소프트웨어 응용 프로그램 간의 통신을 위한 인터페이스입니다. API를 통해 서로 다른 시스템이 데이터를 주고받거나 기능을 호출하여 상호작용할 수 있습니다. 웹에서 사용하는 API는 일반적으로 REST(Representational State Transfer) 방식 또는 GraphQL 방식으로 생성됩니다.

2. JSON 서버란?

JSON 서버는 REST API를 쉽게 생성할 수 있도록 도와주는 도구입니다. 단순한 JSON 파일을 기반으로 RESTful API를 제공하며, 데이터를 CRUD(Create, Read, Update, Delete) 방식으로 관리할 수 있습니다. 이를 통해 프론트엔드 개발자는 쉽게 API와 상호작용할 수 있습니다.

2.1 JSON 서버 설치하기

JSON 서버는 Node.js에서 실행되므로, 먼저 Node.js가 설치되어 있어야 합니다. 그 후 다음 명령어를 통해 JSON 서버를 설치할 수 있습니다:

npm install -g json-server

2.2 JSON 파일 만들기

아래와 같은 형식의 db.json 파일을 생성합니다. 이 파일은 API에서 사용할 데이터의 저장소 역할을 합니다.

{
        "posts": [
            { "id": 1, "title": "첫 번째 포스트", "author": "홍길동" },
            { "id": 2, "title": "두 번째 포스트", "author": "김수빈" }
        ],
        "comments": [
            { "id": 1, "postId": 1, "body": "안녕하세요!" },
            { "id": 2, "postId": 2, "body": "좋은 하루 되세요!" }
        ]
    }

2.3 JSON 서버 실행하기

JSON 서버를 실행하려면 다음 명령어를 입력합니다:

json-server --watch db.json

이 명령어를 통해 로컬 서버가 시작되며, 기본적으로 http://localhost:3000에서 API에 접근할 수 있게 됩니다.

3. 리액트에서 API에 fetch하기

이제 JSON 서버가 실행 중이므로, 리액트 애플리케이션에서 API와 통신하는 방법을 살펴보겠습니다. 리액트 컴포넌트에서 데이터를 가져오기 위해 fetch API를 사용할 수 있습니다.

3.1 리액트 컴포넌트 생성하기

아래는 API로부터 데이터를 받아와서 표시하는 간단한 리액트 컴포넌트입니다:

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

    const Posts = () => {
        const [posts, setPosts] = useState([]);
        const [loading, setLoading] = useState(true);

        useEffect(() => {
            fetch('http://localhost:3000/posts')
                .then(response => response.json())
                .then(data => {
                    setPosts(data);
                    setLoading(false);
                })
                .catch(error => console.error('API 호출 중 오류 발생:', error));
        }, []);

        if (loading) {
            return 
로딩 중...
; } return (

게시글 목록

    {posts.map(post => (
  • {post.title} - {post.author}
  • ))}
); }; export default Posts;

3.2 설명

위의 컴포넌트는 useEffect 훅을 사용하여 컴포넌트가 마운트될 때 API를 호출합니다. fetch 함수를 사용하여 http://localhost:3000/posts URL에서 데이터를 가져오고, 받은 데이터는 setPosts를 통해 상태에 저장합니다. 로딩 상태는 loading 변수를 통해 관리되며, 데이터가 로딩 중일 때 로딩 메시지를 보여주고, 데이터가 모두 로드되면 리스트를 출력합니다.

4. Mock API 사용하기

실제 API를 사용하기 전에 Mock API를 사용하는 것은 매우 유용합니다. Mock API는 실제 서버와 유사한 방식으로 작동하지만, 즉시 구현할 수 있는 APIs입니다. Postman, Mocky, MirageJS와 같은 도구가 있습니다.

4.1 MirageJS 예제

MirageJS는 프론트엔드 개발자들이 테스트와 개발을 위한 API를 설정하는 데 유용합니다. Mirage를 사용하여 API를 설정하는 방법을 살펴보겠습니다.

import { createServer } from 'miragejs';

    createServer({
        routes() {
            this.namespace = 'api';

            this.get('/posts', () => {
                return [
                    { id: 1, title: "Mock API 게시글 1", author: "이순신" },
                    { id: 2, title: "Mock API 게시글 2", author: "박지성" }
                ];
            });
        }
    });

위 코드를 애플리케이션의 엔트리 파일에 추가하면, MirageJS가 설정한 Mock API가 http://localhost:3000/api/posts 경로에서 요청을 받을 수 있습니다. 이제 이전에 작성한 Posts 컴포넌트에서 URL을 변경해주면 Mock API와 통신할 수 있습니다.

4.2 실제 예제와의 비교

MirageJS와 같은 Mock API 기술을 사용하면, 서버가 준비되지 않았더라도 테스트를 할 수 있다는 장점이 있습니다. 또한, Mock API를 사용하면 상호작용과 상태 관리를 더 유연하게 처리할 수 있어 프론트엔드 개발 속도를 높일 수 있습니다.

5. 데이터 업데이트와 삭제

CRUD 작업은 API에서의 기본적인 데이터 처리 방식입니다. 앞에서 작성한 리액트 컴포넌트에서 데이터를 업데이트하고 삭제하는 방법을 알아보겠습니다.

5.1 데이터 업데이트

아래의 코드는 특정 게시글을 업데이트하는 방법을 보여줍니다. fetch 함수에서 PUT 요청을 사용하여 데이터 업데이트 작업을 수행합니다.

const updatePost = (postId, updatedContent) => {
        fetch(`http://localhost:3000/posts/${postId}`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(updatedContent)
        })
        .then(response => response.json())
        .then(updatedPost => {
            // 상태 업데이트 로직
        })
        .catch(error => console.error('게시글 업데이트 오류:', error));
    };

5.2 데이터 삭제

삭제 작업은 DELETE 메소드를 사용하여 수행할 수 있습니다. 아래는 특정 게시글을 삭제하는 예시입니다:

const deletePost = (postId) => {
        fetch(`http://localhost:3000/posts/${postId}`, {
            method: 'DELETE'
        })
        .then(() => {
            // 상태 업데이트 로직
        })
        .catch(error => console.error('게시글 삭제 오류:', error));
    };

6. 결론

리액트에서 API와의 통신을 통해 다양한 데이터를 처리하는 방법을 알아보았습니다. JSON 서버와 같은 진입 장벽이 낮은 도구를 사용하면 개발 초기 단계에서 빠르게 프로토타입을 생성할 수 있으며, Mock API를 통해 실제 API가 개발되기 전에도 유용한 테스트를 진행할 수 있습니다. 이러한 기법들은 프론트엔드 개발의 효율성을 크게 향상시킬 것입니다.

추가 학습자료

이 글이 리액트 및 API의 이해에 도움이 되었기를 바라며, 향후 또 다른 주제로 더욱 심도 깊은 내용을 다룰 수 있기를 기대합니다.

상태 관리 (State)와 이벤트 처리, useState 훅으로 상태 관리하기

React는 컴포넌트 기반의 라이브러리로, 각 컴포넌트는 자신의 상태(state)를 가질 수 있습니다. 상태(state)는 컴포넌트의 데이터와 UI 요소들 간의 연결 고리를 형성하며, 데이터의 변화에 따라 UI가 어떻게 표시될지를 결정합니다. React에서의 상태 관리는 사용자 인터페이스를 더 동적이고 반응적으로 만드는 데 중요한 역할을 합니다.

상태(state)란 무엇인가?

상태(state)는 컴포넌트 내부에서 데이터를 저장하는 객체입니다. 이 상태는 컴포넌트의 렌더링을 유발하며, 상태가 변경될 때마다 React는 새로운 상태를 바탕으로 UI를 업데이트합니다. 이 때, 상태는 컴포넌트가 생성되었을 때의 초기값으로 설정되며, 유저의 입력이나 서버로부터의 응답 등 여러 요인에 따라 변경될 수 있습니다.

상태 관리의 필요성

상태 관리의 중요성은 여러 가지가 있습니다. 데이터의 일관성을 유지하고, 여러 컴포넌트와의 상호작용을 효율적으로 처리하며, 애플리케이션이 UI를 업데이트해야 할 때 어떤 데이터를 보여줘야 하는지를 결정합니다. 예를 들어, 사용자가 버튼을 클릭하여 정보를 입력하거나, API로부터 데이터가 로드될 때 사용자 인터페이스가 반응하도록 만들어야 합니다.

useState 훅 설명

React에서는 함수형 컴포넌트에서 상태를 관리하기 위해 useState 훅을 사용합니다. useState는 React의 내장 훅 중 하나로, 컴포넌트의 상태를 선언하고 변경할 수 있게 해줍니다.

useState의 기본 사용법

useState 훅은 배열을 반환하며, 이 배열은 상태 변수와 상태를 업데이트하는 함수를 포함하고 있습니다. 예를 들어, 상태 변수의 이름을 count라고 하고, 초기값을 0으로 설정한다면 다음과 같이 사용할 수 있습니다:

import React, { useState } from 'react';

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

    return (
        

현재 카운트: {count}

); }; export default Counter;

useState의 동작 방식

위의 예제에서 useState(0) 호출은 count라는 상태 변수를 생성하고, setCount라는 함수를 통해 이 상태를 업데이트할 수 있게 합니다. 버튼을 클릭하면 setCount가 호출되고, 상태가 변경되면 React는 컴포넌트를 다시 렌더링하여 UI를 업데이트합니다.

상태 변수의 초기화

useState의 초기값은 단순한 값일 수도 있지만, 객체나 배열 등 복잡한 데이터 구조도 사용 가능합니다. 초기값이 배열인 경우, 다음과 같이 설정할 수 있습니다.

const [items, setItems] = useState([]);

이벤트 처리

React에서 이벤트 처리는 사용자 인터페이스와 상호작용하는 데 필수적입니다. React는 이벤트를 처리하는 몇 가지 내장 메서드를 제공합니다. 클릭, 입력, 제출 등의 이벤트에 대해 리스너를 지정하여 상태를 업데이트할 수 있습니다.

이벤트 리스너 추가하기

상태를 업데이트하기 위해 버튼 클릭 이벤트에 리스너를 추가하는 예시를 생각해봅시다. 아래 코드는 사용자가 입력한 텍스트를 저장하는 간단한 컴포넌트를 보여줍니다.

import React, { useState } from 'react';

const TextInput = () => {
    const [inputValue, setInputValue] = useState('');

    const handleChange = (e) => {
        setInputValue(e.target.value);
    };

    return (
        

입력한 값: {inputValue}

); }; export default TextInput;

useState의 장점

useState 훅은 여러 가지 장점을 가지고 있습니다. 첫째, 상태 관리를 단순하게 만들어 코드의 가독성을 높입니다. 둘째, 컴포넌트를 다시 렌더링할 때, React가 최신 상태를 바탕으로 UI를 자동으로 업데이트합니다. 셋째, 상태는 로컬하게 컴포넌트 내에서 관리되므로 다른 컴포넌트와 불필요한 복잡성을 줄일 수 있습니다.

상태 업데이트

상태를 업데이트할 때는 setCountsetInputValue와 같이 업데이트 함수를 사용하는 것이 좋습니다. 이들을 사용하는 이유는 React의 상태가 비동기적으로 업데이트되기 때문입니다. 만약 이전 상태에 의존하여 새로운 상태를 결정하고자 한다면, 업데이트 함수를 콜백 형태로 사용할 수 있습니다.

setCount(prevCount => prevCount + 1);

결론

React에서 상태 관리와 이벤트 처리 개념은 매우 중요합니다. useState 훅은 이러한 상태 관리 작업을 단순화하고, 편리하게 컴포넌트를 개발할 수 있도록 도와줍니다. 복잡한 UI를 구성할 때 효과적인 상태 관리는 필수적이며, React의 훅 시스템은 이를 쉽게 처리할 수 있도록 지원합니다.

이 글에서는 React의 상태 관리와 이벤트 처리의 기초를 살펴보았고, 실제 코드 예제를 통해 useState 훅이 어떻게 작동하는지 이해했습니다. 이 내용을 바탕으로 더 복잡한 애플리케이션을 구현하는 데 도움을 줄 수 있을 것입니다. 앞으로도 React의 다양한 훅과 상태 관리 기법을 익혀 나가시길 바랍니다.

추가 자료 및 링크

더 깊이 있는 React의 상태 관리와 이벤트 처리에 대해서는 다음 링크들을 참고해 보시기 바랍니다: