카테고리 없음

Reate 개발환경 구성 과 함수형 컴포넌트

tp134679 2025. 4. 14. 14:54

<목차>

1. reate 디렉토리 구조

2. bev-server 

3. 함수형 컴포넌트 

 

 

 

1. reate 디렉토리 구조

리액트 프로젝트에서는 컴포넌트를 어떻게 조직하는지가 중요합니다. 작업구역과 번들링 할 구역 컴포넌트 구역 등 명확하게 나누기 위해 디렉토리 구조를 잘 짜야합니다.

 

소스 코드 (src) 폴더

src는 source(소스 코드)의 약자,

프로젝트의 핵심 코드가 들어가는 폴더라는 것을  의미합니다.

즉, 애플리케이션이 동작하는데 필요한 원본 코드가 포함된 폴더

웹팩(Webpack)이나 바벨(Babel) 같은 도구가 이 폴더 안의 파일을 읽고 번들링(컴파일)하게 됩니다.

 

/src
│── /pages       # 페이지 단위의 컴포넌트 (라우팅 용도)
   ├── Home.jsx
   ├── About.jsx
   ├── Contact.jsx
│── /components  # 재사용 가능한 UI 컴포넌트
   ├── Button.jsx
   ├── Header.jsx
   ├── Footer.jsx
│── /hooks       # 커스텀 훅(Custom Hooks)
   ├── useFetch.js
│── /styles      # 스타일 파일 (CSS, SCSS, styled-components 등)
   ├── global.css
│── index.jsx    # 애플리케이션 진입점 (entry)
│── App.jsx      # 최상위 컴포넌트

소스 폴더 안에 다시 여러구역으로 나뉜것을 확인할 수 있는데 정리해보자면

 

pages  

pages 폴더는 페이지 단위의 컴포넌트 요청 라우터마다 그에 알맞는 화면을 뿌려줄 컴포넌트를 관리하는 폴더입니다.

화면 단위로 컴포넌트를 분리해놓으면 요청 라우터마다 보여줄 화면이 어디인지 명확하게 표기할 수 있기에 유지보수가 용이합니다.

http://localhost:3000 으로 요청시  Home 컴포넌트가 출력

http://localhost:3000/about 으로 요청시  About 컴포넌트가 출력

 

components 

components 폴더는 재사용이 가능한 UI을 모아두는 곳으로서 사이트를 예로들 경우 상단의 헤더부분과 푸터 부분은 대부분의 사이트가 재사용을 하여 사용하고 있습니다. 이폴더는 그뿐만아니라 버튼이나 이미지 등 재사용이가능한 컴포넌트들을 모아두는 페이지 입니다. 

 

hooks 

 

커스텀 훅(Custom Hooks)을 모아두는 공간입니다.
리액트의 내장 훅(예: useState, useEffect)을 조합하여 반복되는 로직을 재사용 가능하게 만드는 함수를 저장하는 곳입니다. (에러처리 코드 등) 데이터의 캡슐화하여 처리를 가능하게 해줍니다. 

styles

styles 폴더는 애플리케이션의 스타일링을 담당하는 공간입니다

global.css 같은 전역 스타일 파일을 두어 프로젝트 전체에서 일관된 디자인을 유지할 수 있습니다.필요하면 개별 컴포넌트용 CSS, 혹은 styled-components 등의 스타일링 파일도 여기에 배치할 수 있습니다.

 

index.jsx

이 파일은 리액트 애플리케이션의 진입점(entry point)입니다. app.jsx를 불러오는 역활을 합니다.

 

 

App.jsx

애플리케이션의 최상위 컴포넌트로, 모든 페이지와 공통 UI(예: 헤더, 푸터)를 감싸는 역할을 합니다.
보통 여기에서 ReactDOM.createRoot()를 사용하여 App 컴포넌트를 렌더링합니다. index.jsx -> app.jsx 호출 시 렌더링

 

 

 

2. bev-server

bev-server

개발을 도와주는 서버로서  (Development Server) 의 줄임말을 뜻합니다 

코드를 변경할 떄마다 변경된  모듈(파일) 을 파악해서 자동으로 업데이트 해주는 기능을 가지고 있습니다. 

가상돔에서 변경된 상태를 비교하는 것과 혼동 될 수도 있지만. 이건 코드 자체를 수정해도 반영되는 자동 번들링 서버이므로 status 의 변경에 관계가 전혀 없습니다. 

 

특징 

 

1. 자동 번들링, 리로딩  리액트 서버내에서(메모리)를 번들링 해주고 실행시킵니다.

2.HMR (Hot Module Replacement)  브라우저 새로고침 없이 실시간으로 UI 업데이트 가능합니다.

 

 

bev-server 적용법

 

npm install webpack-dev-server

 

webpack config.js 설정 추가 

module.exports = {
    devServer: {
        static: {
            // 정적 파일을 제공하는 폴더를 지정하는 옵션
            directory: path.join(__dirname, "dist")
        },
        // 정적 파일을 gzip압축해서 제공함 => 파일 크기 줄여서 응답속도 빠름
        compress: true,
        port: 3000,
        // 중요! Hot Module Replacement 기능을 활성화하는 옵션
        hot: true,
        historyApiFallback: true
    }

 

static

 

번들링하여 만들어지는  정적인  dist  폴더를 지정합니다.

 

compress

정적 파일을 gzip 압축해서 재공 파일의 응답속도를 높혀줍니다.

 

port

서버을 연결할 port 번호를 나타냅니다. 

 

hot 

Hot Module Replacement(HMR => 핫 모듈 교체)의 줄인말으로 

변경된 모듈(파일)만 찾아서 업데이트 (번들링) 하고 실행합니다. 즉 전체 페이지를 핸더링 하지않아도 변경된 부분만 갱신됨. 실제 파일을 불러오지 않고 메모리 에서 번들링 한 결과를 서빙하기에 속도가 빠릅니다. (핫 리로딩 )

 

historyApiFallback 

옵션은 싱글 페이지 애플리케이션(SPA)에서 클라이언트 사이드 라우팅을 사용할 때 필요한 설정입니다.

 클라이언트 사이드 라우터는 프론트엔드에서 URL을 관리합니다.
예를 들어, http://localhost:3000/about에 접근하면 브라우저는 원래 서버에서 /about 경로를 처리하는 파일을 찾으려고 합니다.

하지만 SPA의 경우 서버에는 /about이라는 실제 파일이 없고, 모든 요청을 index.html로 보내야 합니다.
이때 historyApiFallback: true 설정을 하면 서버가 존재하지 않는 경로 요청을 자동으로 index.html로 리디렉션해줍니다.

 

서버 연결

npm install express

웹팩에서 설정한다고 서버를 만들어주는 것은 아니기에 서버를 설치하여야합니다.이때 서버는 메모리를 옮겨준다고 해서 

서빙이라는 폴더에 만듭니다.

const express = require("express");
const app = express();
const path = require('path');

app.use(express.static(path.join(__dirname, "..", "dist")));

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, "..", "dist/index.html"));
})

app.listen(3000, () => {
    console.log("front server is open");
})

 

packge.json start 설정

"script": {
    "start" : "webpack serve --open --hot"
}

 

3. 함수형 컴포넌트 

함수형 컴포넌트는 기존의 클레스를 사용하는대신 함수를 사용함으로서 좀더 직관적이게 이 가능합니다. 기존의 Reate hooks 가 나오기전에 클레스형 컴포넌트가 많이 사용되었지만 나오고 나서부터는 함수혐 컴포넌트가 주로 사용되고 있다고 합니다.

 

 

클래스형 컴포넌트 와 함수형 컴포넌트 차이점

또한 render 대신에 return 을 사용하여 컴포넌트를 내보냅니다. 

 

 

const Hello = () => {
    return <h1>안녕하세요! </h1>;
};

export default Hello

기존의 클레스형이 아니라 함수형으로 만든 컴포넌트

 

 

useState 상태 관리

 

클레스형의 setState() 함수 대신에 usestate()를 사용합니다. 사용법은

 함수형 컴포넌트 상태

 

const [[상태], [상태변경을알려줄함수]] = useState(기본 상태)

 

import React, { useState } from "react";

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

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

export default Counter;

 

해당 함수를 보면 기본상태 useState 는 0 이고 onClick 이밴트 일때 익명함수로 setCount 함수를 실행 

setCount(count + 1): count 값을 +1 증가

setCount(count - 1): count 값을 -1 감소

 

useEffect  생명주기 관리

 

기존의 componentDidmount 와 componentUpdate 대신에 useEffect   를  사용하여 생명주기를 표현합니다

사용법은 

 

 

 useEffect( () => {요청할 내용}, [변경될 주체가 들어갈곳]  )

 

export const Counter = () => {
    const [value, setValue] = useState(0)


    useEffect(() => {
        console.log("업데이트");
    }, [value])

    return (
        <div>
            <h1>숫자 {value}</h1>
            <button onClick={() => setValue(value + 1)}>+</button>
            <button onClick={() => setValue(value - 1)}>-</button>
        </div>
    )
}

[] 값에 빈값이 들어가면 componentDidmount 처럼 실행될때 한번 실행이 되고

[value] 처럼 변수가 들어가면 변수가 변경이 될때마다 실행되는 componentUpdate 의 기능을 가집니다.