본문 바로가기
웹/24-StudyWithPnP

[React+JS/리액트] 웹 스터디 4주차

by 보먀 2024. 5. 16.
728x90
반응형

class 컴포넌트 만드는 법

 

최근에는 컴포넌트를 만들 때 function 을 사용해 만들지만, 예전 리액트에서는 class 문법을 사용해 만들었다. 

function 사용을 권장하지만, 예전 버전의 리액트 프로젝트를 마주칠 수 있으니 가볍게 공부해 보자.

 

 

class 문법으로 컴포넌트 만드는 법

class Modal2 extends React.Component {
  constructor(){
    super()
  }

  render(){
    return (
      <div>안녕</div>
    )
  }

}

 

1. 클래스명을 작성

2. constructor, super, render 함수를 채워 넣어야 함 -> 무조건 필요한 기본 템플릿이라고 생각하면 된다.

3. 컴포넌트는 길고 복잡한 html 을 축약할 때 쓰기 때문에 return  안에 축약할 html 을 넣으면 된다.

 

extends 는 기존 class 안에 있던 변수, 함수를 복사해주는 문법이다.

React.Component 라는 class 안에 있던 변수와 함수들을 복사해야 컴포넌트라고 인정해주기 때문에 클래스명 뒤에 extends React.Component 를 붙여 줘야한다. 

 

 

※ constructor, super, render 함수 - 참고

 

- constructor : 클래스 컴포넌트가 처음 생성될 때 호출되는 함수로 컴포넌트의 초기 상태(state)를 설정하거나, props 를 통해 전달된 값을 초기화하는 데 사용됨

class MyComponent extends React.Component {
  constructor(props) {
    super(props); // 부모 클래스(React.Component)의 생성자를 호출합니다.
    this.state = {
      count: 0
    };
  }
}

 

  • 컴포넌트의 초기 상태를 정의
  • super(props)를 호출하여 이를 통해 부모 컴포넌트로부터 받은 데이터를 설정할 수 있음
  • super(props)를 호출하여 부모 클래스(React.Component)의 생성자를 호출함으로써 this.props 를 사용할 수 있음

- super : 부모 클래스의 생성자를 호출하는 역할을 한다. js 에서 클래스는 상속을 통해 만들어지므로 리액트 클래스 컴포넌트는 React.Component 를 상속받는다. 따라서 생성자 내에서 super 를 호출해야 this 를 사용할 수 있다. 

constructor(props) {
  super(props);
  // 이제 this를 사용할 수 있음
}
  • 부모 클래스의 생성자를 호출하여 부모 클래스의 초기화 과정을 수행
  • super(props) 를 호출하여 부모 클래스에 props 를 전달함으로써 부모 클래스에서도 props 를 사용할 수 있게 함

- render : 리액트 컴포넌트에서 반드시 구현해야 하는 메서드로, 컴포넌트의 UI 를 정의한다. 이 함수는 JSX 를 반환하며, 리액트는 이를 기반으로 가상 DOM 을 생성하고 실제 DOM 에 반영한다.

class MyComponent extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello, {this.props.name}</h1>
        <p>Count: {this.state.count}</p>
      </div>
    );
  }
}
  • 컴포넌트의 UI 를 정의하고 반환
  • JSX 를 반환하며, 리액트는 이를 바탕으로 UI 를 렌더링
  • 컴포넌트의 상태(state)나 속성(props)에 따라 동적으로 UI 를 변경할 수 있음

 

class 컴포넌트에서 state 만들기

class Modal2 extends React.Component {
  constructor(){
    super();
    this.state = {
      name : 'kim',
      age : 20
    }
  }

  render(){
    return (
      <div>
      	<div>안녕 { this.state.name }</div>
        <button onClick={()=>{ this.setState({age: 21}) }}>버튼</button>
      </div>
    )
  }

}

 

위의 참고 부분에서 설명했듯이 constructor 는 클래스 컴포넌트가 처음 생성될 때 호출되는 함수로 컴포넌트의 초기 상태(state)를 설정하기 때문에 state 를 설정해 주려면 constructor 안에 object 형식으로 state 를 나열하면 된다. 

 

state 는 this.setState 라는 기본함수로 변경할 수 있다. setState 는 state 자체를 통채로 바꾸는 것이 아니라 기존 state 값과 비교해 차이가 있는 부분만 변경하여 준다. 

 

 

class 컴포넌트에서 props 

class Modal2 extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      name : 'kim',
      age : 20
    }
  }

  render(){
    return (
      <div>안녕 { this.props.프롭스이름 }</div>
    )
  }

}

 

만약 부모가 보낸 props 를 출력하고 싶다면 constructor, super 에 props 파라미터를 등록하고 this.props 를 사용하면 props 가 출력된다.

 

 

 

만든 리액트 사이트 build & Github Pages로 배포해보기

만든 사이트를 배포하려면 build 용 파일을 생성한 후 그 파일을 올려한다. 

(웹브라우저는 HTML CSS JS 이 세 개의 언어만 해석할 수 있기 때문, 리액트의 state 나 JSX 은 알아듣지 못함)

 

그래서 리액트 프로젝트를 build 하여 브라우저 친화적인 HTML CSS JS 파일로 바꾼 후, 서버에 올리면 된다.

 

 

0. 배포 전 체크할 사항

  • 미리 보기를 띄워볼 때 콘솔창, 터미널 에러 안나면 ok, warning 메세지는 사이트 구동에 별 영향이 없으므로 테스트 땐 무시해도 됨
  • 사이트를 배포할 때 사이트의 하위 경로에 배포하는 경우 프로젝트에 설정이 따로 필요                                                                    기본경로-https://www.naver.com   하위경로-https://www.naver.com/blog

하위 경로에 배포하는 경우에는 프로젝트 파일 중 pakage.json 파일을 오픈 후 아래와 같이 homepage 항목을 추가하고 배포할 사이트의 경로를 적어주면 된다. ("homepage": "/blog", 도 가능)

"homepage": "http://www.naver.com/blog",

 

그리고 리액트 라우터를 설치하고 라우터가 제공하는 basename="" 속성을 추가하면 라우팅이 더 잘된다고 한다.

(더 자세한 내용은 링크를 참고하자. https://create-react-app.dev/docs/deployment/#building-for-relative-paths)

 

 

1. 터미널에 build 명령어 입력

 

state, JSX, <컴포넌트>, props 문법들은 브라우저가 해석할 수 없으니 HTML, CSS, JS 로 바꾸어 주는 작업이 필요한데, 

그 작업을 컴파일 또는 build 라고 한다. 

방법은 간단하다. 터미널을 켜고 해당 프로젝트 디렉토리로 들어가서 아래의 명령어를 입력하면 된다.

npm run build

 

빌드가 끝나면 프로젝트 폴더에 build 라는 폴더가 생긴 것을 확인할 수 있는데, 내가 작업한 파일들이 .html .css .js 파일로 변환되어 담겨있다. build 폴더 안에 있는 내용을 모두 서버에 올리면 된다. index.html 이 메인페이지가 된다. 

 

 

2. 하지만 서버가 없다면?  github pages 

 

github pages 는 HTML CSS JS 파일을 무료로 호스팅해주는 사이트이다. 

깃허브에 로그인하고 들어가서 레포를 만드는 창으로 들어가서 레포 이름을 내 깃허브이름.github.io 로 설정해주고, 

README 파일 생성도 체크해주면 된다. 

 

 

3. 레포에 html 파일 올리기

 

레포 생성이 끝나면 build 폴더 내에 있는 파일을 몽땅 레포에 올리면 완성이다.

즉각적으로 반영되지 않으니 10 분정도 기다린 후 https://내깃허브이름.github.io 에 들어가면 사이트를 볼 수 있다. 

 

 

리액트 Bootstrap 사용하기

 

리액트 부트스랩이란 레이아웃을 쉽게 짤 수 있도록 해주는 리액트용 컴포넌트 라이브러리이다. 

 

먼저 리액트 부트스트랩을 사용하기 위해 프로젝트 폴더에서 터미널을 열고 리액트 부트스트랩을 설치해보자.

(명령어는 자주 바뀐다고 하니 리액트 부트스트랩 홈페이지 가서 확인하고 설치하는 것을 추천한다)

npm install react-bootstrap bootstrap

 

 

컴포넌트를 사용할 때 부트스트랩 CSS 파일을 요구하는 경우가 있다하니 아래의 두 가지 방법 중에 한 가지를 선택해서 세팅한 후에 리액트 부트스트랩을 사용하면 된다.

  • index.html 로 가서 <head> 안에 아래의 코드를 붙여넣기
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
  integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
  crossorigin="anonymous"
/>
  • App.js 에 import 'bootstrap/dist/css/bootstrap.min.css'; 추가하기

 

리액트 부트스트랩 사용법

 

필요한 컴포넌트를 사이트에서 검색하고 복사해와서 사용하면 된다. 주의해야 할 점은 컴포넌트의 이름이 대문자로 시작하는 경우는 import 가 필요하니 import { Button } from 'react-bootstrap' 을 추가해주어야 한다. 

 

 

리액트에서 이미지 넣기

 

css 파일에서 이미지 넣기

.main-bg {
  height : 300px;
  background-image : url('./bg.png');
  background-size : cover;
  background-position : center;
}

 

css 파일에서 src 폴더 안에 있는 사진을 사용하고 싶으면 url('./이미지경로') 를 사용하면 된다.

 

 

html 파일에서 이미지 넣기

 

html 파일에서 src 폴더에 있는 이미지를 사용하려면 이미지를 import 해 온 후에 사용할 수 있다.

import 이름 from './bg.png'

function App(){
  return (
    <div>
      <div className="main-bg" style={{ backgroundImage : 'url(' + 이름 + ')' }}></div>
    </div>
  )
}

 

- import 이름 from './이미지경로'

- 이미지 태그를 쓰는 경우에는 이렇게 쓰면 된다. <img src={ 이름 } />

 

※ style={{ backgroundImage : 'url(' + bg + ')' }} 형식을 사용해야 하는 이유

자바스크립트 문자열 연결 방식을 사용해서 연결해준 것

 

 

뜬금없지만 알아두면 편한 화면을 가로로 삼등분 하는 코드

<div className="container">
  <div className="row">
    <div className="col-md-4">안녕</div>
    <div className="col-md-4">안녕</div>
    <div className="col-md-4">안녕</div>
  </div>
</div>

 

 

public 폴더의 용도

 

보통 여러 소스 코드들은 src 에 보관을 합니다. 개발이 끝나면 지금까지 짯던 코드들을 한 파일로 압축하는 build 를 하고 src 폴더의 여러 파일들은 압축이 됩니다. 하지만 public 폴더에 있는 파일들은 압축 대상이 아니기 때문에 압축되지 않고 보존됩니다.

그래서 형태를 보존하고 싶은 파일을 public 폴더에 넣어 보관하면 됩니다. 그래서 이미지, txt, json 등 수정이 필요없는 static 파일들을 public 폴더에 보관하기도 합니다. 

 

 

public 폴더에 있는 이미지 사용하기

 

html, css 파일에서 이미지 사용을 위해서는 '/이미지경로' 를 사용하면 됩니다. public 폴더에 있는 이미지를 쓰면 src 폴더에 있는 이미지를 쓸 때와 다르게 import 할 필요가 없기 때문에 간편하게 사용할 수 있습니다. 

<img src="/logo192.png" />

 

하지만, 이 방식은 서브 경로에 사이트를 배포하게 되면 파일을 찾을 수 없는 문제가 생길 수 있기 때문에 아래와 같이 사용하는 것을 권장합니다. (서브 경로에 배포하는 경우가 아니라면 사용하지 않아도 됨)

<img src={process.env.PUBLIC_URL + '/logo192.png'} />

 

 

 

코드가 길어지면 import, export 

 

한 파일에서 내보내야할 변수 1개: export default / import

 

data 라는 state 에 아래의 배열을 넣어 초기화 시켜주었는데, 코드가 길어 복잡합니다. 이런 경우에는 복잡한 코드 부분을 다른 파일에 보관했다가 import 하여 사용할 수 있습니다. 

let [a] = useState(
[
  {
    id : 0,
    title : "White and Black",
    content : "Born in France",
    price : 120000
  },

  {
    id : 1,
    title : "Red Knit",
    content : "Born in Seoul",
    price : 110000
  },

  {
    id : 2,
    title : "Grey Yordan",
    content : "Born in the States",
    price : 130000
  }
]
);

 

// data.js 

let data = [
  {
    id : 0,
    title : "White and Black",
    content : "Born in France",
    price : 120000
  },

  {
    id : 1,
    title : "Red Knit",
    content : "Born in Seoul",
    price : 110000
  },

  {
    id : 2,
    title : "Grey Yordan",
    content : "Born in the States",
    price : 130000
  }
]

export default data;

 

// App.js

import data from './data.js';

let [a] = useState(data);

 

이렇게 배열을 data.js 파일로 분리시키고 export 시킨 후 dataApp.js 파일에서 import 시켜서 쓰면 훨씬 깔끔하게 코드를 짤 수 있다. 

 

 

한 파일에서 내보내야할 변수가 여러 개: export { } / import { }

// data.js

var name1 = 'Kim';
var name2 = 'Park';
export { name1, name2 }
// App.js
import { name1, name2 } from './data.js';

 

 

정리

- 내보내야 할 변수가 1개라면 export default 변수명 / import 변수명

- 내보내야 할 변수가 여러 개라면 export { 변수명, 변수명, ... } / import { 변수명, 변수명, ... }

- 변수, 함수, 자료형 전부 export 가능

- 파일 당 export  default  라는 키워드는 하나만 사용 가능

- 파일 경로는 ./ 부터 시작해야 함

- export { } 했던 것들은 import { } 할 때 자유작명 불가능, export 했던 변수명 그대로 적어야 함

 

 

숙제:

1. 오늘 만든 상품목록을 컴포넌트로 만들기, 컴포넌트도 길면 다른 파일로 빼도 상관없음

2. 컴포넌트만들면 그 안에 데이터바인딩도 아마 다시하기

3. 반복적인 html이나 컴포넌트를 발견하면 연습삼아 map 반복문을 써보기 

 

// items.js

import React from "react";
import data from "./data.js"
import { Col, Row, Container, Nav, Navbar } from 'react-bootstrap';

function Item() {
    return (
        <div>
            <Row>
            {
                data.map((d, i)=> {
                    return (
                        <Col>
                            <img src={`https://codingapple1.github.io/shop/shoes${i+1}.jpg`} width={"80%"}></img>
                            <h4>{data[i].title}</h4>
                            <p>{data[i].price}</p>
                        </Col>  
                    );
                })
            }
            </Row> 
        </div>
    );
}

export default Item;
// App.js

import './App.css';
import { Col, Row, Container, Nav, Navbar } from 'react-bootstrap';
import React, { useState } from 'react';
import data from './data.js';
import Items from './items.js'

function App() {

  let [shoes] = useState(data);

  return (
    <div className="App">
      <Navbar bg="dark" data-bs-theme="dark">
          <Container>
          <Navbar.Brand href="#home">Navbar</Navbar.Brand>
          <Nav className="me-auto">
            <Nav.Link href="#home">Home</Nav.Link>
            <Nav.Link href="#features">Features</Nav.Link>
            <Nav.Link href="#pricing">Pricing</Nav.Link>
          </Nav>
        </Container>
      </Navbar>

      <div className='main-bg'></div>
      <div>
        <Container>
          <Items></Items>
        </Container>
       </div>
    </div>
  );
}

export default App;
728x90
반응형