React - 04

월요일좋아·2023년 1월 3일
0

React

목록 보기
4/11

프로젝트 생성

2.7.0 버전 리액트 부트스트랩을 원래는 다운로드 받아서 써야 하는데 지금껏 사용해온 부트스트랩 방식과 너무 달라서 익히는데 시간이 걸림
-> 부트스트랩 홈페이지에 있는 코드 붙여넣으면 사용하던 방식과 유사하게 쓸 수 있음
https://getbootstrap.com/

  • index.html
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
    <title>React App</title>
  • App.js
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <button type={"button"}>기본 버튼</button>
      <button type={"button"} className={"btn btn-primary"}>부트스트랩 적용 버튼</button>
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>


    </div>
  );
}

export default App;

리액트 부트스트랩을 사용하고 싶다면 터미널창에서 현재 프로젝트까지 경로 설정 후 명령어 쓰기(node.js 는 폴더를 기반으로 위치를 지정하기 때문)
npm install react-bootstrap bootstrap

App.js

import Button from "react-bootstrap/Button";

위와 같이 필요한 기능만 import 해서 사용 (사용법은 리액트 공식문서(https://ko.reactjs.org/)에서 확인)

<button type={"button"}>기본 버튼</button>
<button type={"button"} className={"btn btn-primary"}>부트스트랩 적용 버튼</button>
<Button type={"button"} variant={"success"}>react용 부트스트랩 적용 버튼</Button>


문법

JSX

자바스크립트 + html/xml, 하나의 파일에 자바스크립트와 html 을 동시에 작성

컴포넌트

  1. 함수형 컴포넌트 : 현재 많이 사용되는 방식, 사용이 간편함 (클래스형 컴포넌트의 기능을 100% 대체할 수 있음), 자바스크립트 함수를 작성하는 방식
  2. 클래스형 컴포넌트 : 기존에 많이 사용되던 방식, React.Component 를 상속받아 구현함, 컴포넌트 구성요소, 리액트 생명주기를 모두 포함하고 있음
  • 리액트를 구성하는 최소 UI 단위, 데이터(props)를 입력받아 view(state)상태에 따라 화면을 출력하는 함수
  • 컴포넌트의 이름은 항상 대문자로 시작 (리액트는 소문자로 시작하는 컴포넌트를 html 태그로 인식함 -> html 태그는 <button>, 리액트 컴포넌트는 <Button>)
  • UI 를 재사용 가능한 개별적인 여러 조각으로 나누어서 화면 구현

props

컴포넌트간의 데이터를 주고 받기 위한 JS 객체, properties 의 줄임말, 읽기 전용, 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달 시 주로 사용

state

현재 컴포넌트의 상태를 표시하는 객체, setState() 를 통해서 데이터를 수정, 데이터 수정 시 화면에 재렌더링됨

hooks

리액트 16.8버전에서 추가된 기능, 상태 변경 및 리액트 생명주기에 관련된 함수를 사용할 수 있게 해주는 기능, 리액트 hooks 를 사용하면 클래스 컴포넌트를 사용할 필요가 없음

컨텍스트

데이터 전달 객체, 컴포넌트 간의 데이터 전달 시 props 를 사용하면 순차적으로 데이터를 전달함, 컨텍스트는 위치에 상관없이 데이터를 바로 전달할 수 있음

전체 화면 내부에 메인화면이 있고 그 내부에 작은화면 A, B 로 나눠진다면 전체에서 B로 데이터를 바로 전달하는것이 불가능함

전체에서 메인으로 보내고, 메인에서 B로 보내야 함(순차적으로)

이것이 간단한 화면에서는 문제가 되지 않지만 화면이 복잡해지면 계속해서 함수를 만들어줘야함(사용하지 않는 화면(ex: main) 에서도)

이것을 쉽게 해주는것이 컨텍스트이다. 전체에서 컨텍스트로 -> 컨텍스트에서 바로 B로

react-router

각 페이지의 경로를 구성하는 라이브러리.

리액트는 싱글 페이지이기 때문에 화면이 하나밖에 없음. 내부 컨텐츠만 바뀌면서 움직일 뿐. (= 리액트 라우터) 클릭을 하면 다른 페이지가 열린것처럼 보이지만 사실은 내부에서 컨텐츠가 움직이고 사라지고 보이게 된 것


JSX 문법

  1. 반드시 1개의 부모 요소가 다른 요소를 감싸는 형태로 구성해야 함(부모 요소가 하나이기만 하면 <div>가 아니라 <p> 태그도 부모요소가 될 수 있음

  2. 자바스크립트 표현식 사용 가능

  • 2-1. { } 안에 자바스크립트를 사용할 수 있음
    • App.js
function App() {
  let num1 = 10;
  return (
    <div className="App">
      <button type={"button"}>기본 버튼</button>
      <button type={"button"} className={"btn btn-primary"}>부트스트랩 적용 버튼</button>
      <Button type={"button"} variant={"success"}>react용 부트스트랩 적용 버튼</Button>

      <p>{num1 + 10}</p>
  • 2-2 if 문은 표현식이 아니기 때문에 JSX 에서 사용할 수 없음 (대신에 삼항연산자를 사용해야 함)
    { } 표현식 내에서 자바스크립트의 if 문을 사용할 수 없으므로 외부에서 미리 계산
    • App.js
function App() {
  let num1 = 10;
  const flag = false;
  let result;

  // {} 표현식 내에서 자바스크립트의 if 문을 사용할 수 없으므로 외부에서 미리 계산
  if (flag) {
    result = <div>결과가 true</div>
  } else {
    result = <div>결과가  false</div>
  }
  return (
    <div className="App">
      <button type={"button"}>기본 버튼</button>
      <button type={"button"} className={"btn btn-primary"}>부트스트랩 적용 버튼</button>
      <Button type={"button"} variant={"success"}>react용 부트스트랩 적용 버튼</Button>

      <p>{num1 + 10}</p>
      <br/><hr/>
      {/* if 쓰면 바로 에러남! 사용하고 싶으면 삼항연산자 사용하기*/}
      {/*{if (flag) {*/}
      {/*  */}
      {/*}}*/}
      {/* if 문 사용할 수 없어서 삼항연산자 사용함*/}
      <div>{flag === true ? 100 : 10}</div>
      <div>{result}</div>
  1. html 속성을 카멜명명법으로 사용
    font-size -> fontSize 로 사용함
    class -> className 으로 사용
  2. JSX 문법은 html 태그 사용 시, 반드시 시작 태그와 끝 태그를 모두 입력해야 함
    축약 형식으로 시작 태그 끝에 / 를 사용하는 방식도 상관없음

컴포넌트

클래스 컴포넌트

  1. 모든 컴포넌트는 React 를 import 해서 사용함
  2. 클래스 컴포넌트는 React.Component 상속받아 클래스를 생성
  3. 클래스 컴포넌트를 export default 로 설정해줘야 외부에서 사용이 가능함
  • ClassComponent.jsx
import React from "react";

class ClassComponent extends React.Component {

}

export default ClassComponent;
  1. 클래스 컴포넌트에는 render() 메소드가 존재함, render() 메소드에서 jsx 문법을 사용함
  2. 클래스 컴포넌트는 리액트 생명주기 메소드를 사용할 수 있음
  3. 생성자(constructor) 사용가능, 상태 표현을 위한 state 를 설정(없으면 안써도 됨)
  • ClassComponent.jsx : 기본형
import React from "react";

class ClassComponent extends React.Component {

  constructor(props) {
    super(props);
    this.state = {}
  }

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

  componentDidMount() {
  }
}

export default ClassComponent;

함수 컴포넌트 (훨씬 사용이 간단!)

  1. 모든 컴포넌트는 React 를 import 해서 사용함
  2. 함수 컴포넌트는 그냥 함수 생성
  3. 함수 컴포넌트를 export default 로 설정해줘야 외부에서 사용이 가능함
  4. 함수 컴포넌트에서는 return 에서 jsx 문법을 사용함
  • FunctionComponent.jsx
import React from "react";

function FunctionComponent(props) {
  return (
    <div>
      <p>함수 컴포넌트 사용</p>
    </div>
  );
}

export default FunctionComponent;
  1. state 변경 및 생명주기에 관련된 함수를 사용하기 위해서 hooks 를 사용함
    import {useState} from "react";
import React, {useState} from "react";

App.js의 return (...) 내부에 코드 추가

<ClassComponent/>
<FunctionComponent/>


화면 그려보기 실습

App2.jsx 파일 생성

  • App2.jsx 기본형 만들기
// App2.jsx
import React from "react";

function App2() {
  return (
    <div>

    </div>
  );
}


export default App2;

Index.js 의 <App/> 주석처리 후 <App2/> 추가

// Index.js
root.render(
  <React.StrictMode>
    {/*<App />*/}
    <App2 />
  </React.StrictMode>
);

화면 열어보면 빈 화면, F12로 확인해보면 root 내부의 <div> 태그가 비어있는것 확인 가능

App2.jsx : 기본 페이지 만들기

// App2.jsx
// App2.jsx
import React from "react";

// object 타입
const styles = {
  fakeImg: {
    height: 200,
    backgroundColor: "#aaa",
  },
};

function App2() {
  return (
    <div>
      <div className={"p-5 bg-primary text-white text-center"}>
        <h1>컴포넌트 연습용 부트스트랩 기본 페이지 만들기 1</h1>
        <p>반응형 웹이 지원하는 페이지임</p>
      </div>

      <nav className={"navbar navbar-expand-sm bg-dark navbar-dark"}>
        <div className={"container-fluid"}>
          <ul className={"navbar-nav"}>
            <li className={"nav-item"}>
              <a className={"nav-link active"} href={"#"}>Active</a>
            </li>
            <li className={"nav-item"}>
              <a className={"nav-link"} href={"#"}>Link</a>
            </li>
            <li className={"nav-item"}>
              <a className={"nav-link"} href={"#"}>Link</a>
            </li>
            <li className={"nav-item"}>
              <a className={"nav-link disabled"} href={"#"}>Disabled</a>
            </li>
          </ul>
        </div>
      </nav>

      <div className={"container mt-5"}>
        <div className={"row"}>
          <div className={"col-sm-4"}>
            <h2>About Me</h2>
            <h5>Photo of me:</h5>
            <div style={styles.fakeImg}>Fake Image</div>
            <p>아무 노래나 일단 틀어~~</p>
            <ul className={"nav nav-pills flex-column"}>
              <li className={"nav-item"}>
                <a className={"nav-link active"} href="#">Active</a>
              </li>
              <li className={"nav-item"}>
                <a className="nav-link" href={"#"}>Link</a>
              </li>
              <li className={"nav-item"}>
                <a className="nav-link" href={"#"}>Link</a>
              </li>
              <li className={"nav-item"}>
                <a className="nav-link disabled" href={"#"}>Disabled</a>
              </li>
            </ul>
            <hr className={"d-sm-none"}/>
          </div>
          <div className={"col-sm-8"}>
            <h2>제목 부분</h2>
            <h5>부제목 부분, 2023-01-03</h5>
            <div style={styles.fakeImg}></div>
            <p>점심 먹고 싶다 배고프다</p>
            <p>리액트 수업 듣는 중... 오전 11:14</p>

            <h2>제목 부분</h2>
            <h5>부제목 부분, 2023-01-03</h5>
            <div style={styles.fakeImg}></div>
            <p>점심 먹고 싶다 배고프다222</p>
            <p>리액트 수업 듣는 중... 오전 11:15</p>
          </div>
        </div>
      </div>
      <div className={"mt-5 p-4 bg-dark text-white text-center"}>
        <p>Footer</p>
      </div>
    </div>
  );
}


export default App2;


  • Contents.jsx 기본 코드
// Contents.jsx
import React from "react";

function Contents() {
  return (
    <div>

    </div>
  );
}

export default Contents;

화면 조각내기 - 1

  • App2.jsx
// App2.jsx
import React from "react";
import Contents from "./Contents";
import Footer from "./Footer";
import Header from "./Header";
import Navigate from "./Navigate";
import LinkList from "./LinkList";
import Info from "./Info";

// object 타입
const styles = {
  fakeImg: {
    height: 200,
    backgroundColor: "#aaa",
  },
};

function App2() {
  return (
    <div>
      <Header/>
      {/* ------------------- Header.jsx 로 이동 ------------------------*/}
      {/*<div className={"p-5 bg-primary text-white text-center"}>*/}
      {/*  <h1>컴포넌트 연습용 부트스트랩 기본 페이지 만들기 1</h1>*/}
      {/*  <p>반응형 웹이 지원하는 페이지임</p>*/}
      {/*</div>*/}

      <Navigate/>
      {/*------------------- Navigate.jsx 로 이동 ------------------------*/}
      {/*<nav className={"navbar navbar-expand-sm bg-dark navbar-dark"}>*/}
      {/*  <div className={"container-fluid"}>*/}
      {/*    <ul className={"navbar-nav"}>*/}
      {/*      <li className={"nav-item"}>*/}
      {/*        <a className={"nav-link active"} href={"#"}>Active</a>*/}
      {/*      </li>*/}
      {/*      <li className={"nav-item"}>*/}
      {/*        <a className={"nav-link"} href={"#"}>Link</a>*/}
      {/*      </li>*/}
      {/*      <li className={"nav-item"}>*/}
      {/*        <a className={"nav-link"} href={"#"}>Link</a>*/}
      {/*      </li>*/}
      {/*      <li className={"nav-item"}>*/}
      {/*        <a className={"nav-link disabled"} href={"#"}>Disabled</a>*/}
      {/*      </li>*/}
      {/*    </ul>*/}
      {/*  </div>*/}
      {/*</nav>*/}

      <div className={"container mt-5"}>
        <div className={"row"}>
          <div className={"col-sm-4"}>
            <Info/>
            {/* ----------------------- Info.jsx 로 이동 -----------------------*/}
            {/*<h2>About Me</h2>*/}
            {/*<h5>Photo of me:</h5>*/}
            {/*<div style={styles.fakeImg}>Fake Image</div>*/}
            {/*<p>아무 노래나 일단 틀어~~</p>*/}

            <LinkList/>
            {/* ----------------------- LinkList.jsx 로 이동 -----------------------*/}
            {/*<ul className={"nav nav-pills flex-column"}>*/}
            {/*  <li className={"nav-item"}>*/}
            {/*    <a className={"nav-link active"} href="#">Active</a>*/}
            {/*  </li>*/}
            {/*  <li className={"nav-item"}>*/}
            {/*    <a className="nav-link" href={"#"}>Link</a>*/}
            {/*  </li>*/}
            {/*  <li className={"nav-item"}>*/}
            {/*    <a className="nav-link" href={"#"}>Link</a>*/}
            {/*  </li>*/}
            {/*  <li className={"nav-item"}>*/}
            {/*    <a className="nav-link disabled" href={"#"}>Disabled</a>*/}
            {/*  </li>*/}
            {/*</ul>*/}
            <hr className={"d-sm-none"}/>
          </div>
          <div className={"col-sm-8"}>
            <Contents/>
            {/*------------Contents.jsx 로 이동----------------*/}
            {/*<h2>제목 부분</h2>*/}
            {/*<h5>부제목 부분, 2023-01-03</h5>*/}
            {/*<div style={styles.fakeImg}></div>*/}
            {/*<p>점심 먹고 싶다 배고프다</p>*/}
            {/*<p>리액트 수업 듣는 중... 오전 11:14</p>*/}

            <Contents/>
            {/*------------Contents.jsx 로 이동----------------*/}
            {/*<h2>제목 부분</h2>*/}
            {/*<h5>부제목 부분, 2023-01-03</h5>*/}
            {/*<div style={styles.fakeImg}></div>*/}
            {/*<p>점심 먹고 싶다 배고프다</p>*/}
            {/*<p>리액트 수업 듣는 중... 오전 11:14</p>*/}
          </div>
        </div>
      </div>

      <Footer/>
      {/*------------Footer.jsx 로 이동----------------*/}
      {/*<div className={"mt-5 p-4 bg-dark text-white text-center"}>*/}
      {/*  <p>Footer</p>*/}
      {/*</div>*/}
    </div>
  );
}


export default App2;
  • navigate.jsx
// Navigate.jsx

import React from "react";

function Navigate() {
  return(
    <div>
      <nav className={"navbar navbar-expand-sm bg-dark navbar-dark"}>
        <div className={"container-fluid"}>
          <ul className={"navbar-nav"}>
            <li className={"nav-item"}>
              <a className={"nav-link active"} href={"#"}>Active</a>
            </li>
            <li className={"nav-item"}>
              <a className={"nav-link"} href={"#"}>Link</a>
            </li>
            <li className={"nav-item"}>
              <a className={"nav-link"} href={"#"}>Link</a>
            </li>
            <li className={"nav-item"}>
              <a className={"nav-link disabled"} href={"#"}>Disabled</a>
            </li>
          </ul>
        </div>
      </nav>
    </div>
  );
}

export default Navigate;
  • Info.jsx
// Info.jsx

import React from "react";

const styles = {
  fakeImg: {
    height: 200,
    backgroundColor: "#aaa",
  },
};

function Info() {
  return (
    <div>
      <h2>About Me</h2>
      <h5>Photo of me:</h5>
      <div style={styles.fakeImg}>Fake Image</div>
      <p>아무 노래나 일단 틀어~~</p>
    </div>
  );
}

export default Info;
  • LinkList.jsx
// LinkList.jsx
import React from "react";

function LinkList() {
  return (
    <div>
      <ul className={"nav nav-pills flex-column"}>
        <li className={"nav-item"}>
          <a className={"nav-link active"} href="#">Active</a>
        </li>
        <li className={"nav-item"}>
          <a className="nav-link" href={"#"}>Link</a>
        </li>
        <li className={"nav-item"}>
          <a className="nav-link" href={"#"}>Link</a>
        </li>
        <li className={"nav-item"}>
          <a className="nav-link disabled" href={"#"}>Disabled</a>
        </li>
      </ul>
    </div>
  );
}

export default LinkList;
  • Contents.jsx
// Contents.jsx
import React from "react";
// object 타입
const styles = {
  fakeImg: {
    height: 200,
    backgroundColor: "#aaa",
  },
};

function Contents() {
  return (
    <div>
      <h2>제목 부분</h2>
      <h5>부제목 부분, 2023-01-03</h5>
      <div style={styles.fakeImg}></div>
      <p>점심 먹고 싶다 배고프다</p>
      <p>리액트 수업 듣는 중... 오전 11:14</p>
    </div>
  );
}

export default Contents;
  • Header.jsx
// Header.jsx

import React from "react";

function Header() {
  return(
    <div>
      <div className={"p-5 bg-primary text-white text-center"}>
        <h1>컴포넌트 연습용 부트스트랩 기본 페이지 만들기 1</h1>
        <p>반응형 웹이 지원하는 페이지임</p>
      </div>
    </div>
  );
}

export default Header;
  • Footer.jsx
// Footer.jsx

import React from "react";

function Footer() {
  return(
      <div className={"mt-5 p-4 bg-dark text-white text-center"}>
        <p>Footer</p>
      </div>
  );
}

export default Footer;

props

자바스크립트 컴포넌트 간의 데이터 전달을 위해서 사용하는 자바스크립트 객체, 읽기 전용
부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달 시 사용
부모 컴포넌트에서 자식 컴포넌트를 호출하여 사용 시 속성을 사용하여 데이터를 전달
부모 컴포넌트에서 사용한 속성명이 자식 컴포넌트의 props 객체에 담겨서 전달이 됨
해당 속성명을 자식 컴포넌트에서 그대로 사용함

  • App3.jsx
import React from "react";
import ProfileList from "./folder1/ProfileList";

function App3() {
  return(
    <div>
      <ProfileList />
    </div>
  );
}

export default App3;
  • folder1/Profile.js
// folder1/Profile.jsx

import React from "react";

function Profile(props) {
  return (
    <div className={"border rounded-2 px-3 m-4"}>
      <div className={"my-3"}>
        <label for={"user-id"} className={"form-label"}>아이디 : </label>
        <input type={"text"} id={"user-id"} className={"form-control"} value={props.userId}/>
      </div>
      <div className={"my-3"}>
        <label for={"user-name"} className={"form-label"}>이름 : </label>
        <input type={"text"} id={"user-name"} className={"form-control"} value={props.userName}/>
      </div>
      <div className={"my-3"}>
        <label for={"user-tel"} className={"form-label"}>전화번호 : </label>
        <input type={"tel"} id={"user-tel"} className={"form-control"} value={props.userTel}/>
      </div>
      <div className={"my-3"}>
        <label for={"user-email"} className={"form-label"}>이메일 : </label>
        <input type={"email"} id={"user-email"} className={"form-control"} value={props.userEmail}/>
      </div>
    </div>
  );
}

export default Profile;
  • folder2/ProfileList.jsx
// folder1/ProfileList.jsx

import React from "react";
import Profile from "./Profile";

/*
props : 자바스크립트 컴포넌트 간의 데이터 전달을 위해서 사용하는 자바스크립트 객체, 읽기 전용
        부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달 시 사용
        부모 컴포넌트에서 자식 컴포넌트를 호출하여 사용 시 속성을 사용하여 데이터를 전달
        부모 컴포넌트에서 사용한 속성명이 자식 컴포넌트의 props 객체에 담겨서 전달이 됨
        해당 속성명을 자식 컴포넌트에서 그대로 사용함
*/

function ProfileList() {
  return (
    <div className={"row"}>
      <div className={"col-sm-6 mx-auto"}>
        <Profile userId={"test1"} userName={"테스터1"} userTel={"01012345678"} userEmail={"test1@bitc.co.kr"}/>
      </div>
    </div>
  );
}

export default ProfileList;

값을 변경하고싶다면 자바스크립트 변수 생성해서 사용

  let data = props;
  let userTel = props.userTel;
  let userEmail = props.userEmail;
  • Profile.js
// folder1/Profile.jsx

import React from "react";

// function Profile({userId, userName, userTel, userEmail}) {...} 로도 사용 가능(확장표현식)
// 확장표현식 : 대입 연산자 오른쪽의 데이터를 연산자 왼쪽의 변수에 저장 시 () {} 에 표시된 이름에 대입
function Profile(props) {
  let data = props;
  let userTel = props.userTel;
  let userEmail = props.userEmail;

  return (
    <div className={"border rounded-2 px-3 m-4"}>
      <div className={"my-3"}>
        <label for={"user-id"} className={"form-label"}>아이디 : </label>
        <input type={"text"} id={"user-id"} className={"form-control"} value={data.userId}/>
      </div>
      <div className={"my-3"}>
        <label for={"user-name"} className={"form-label"}>이름 : </label>
        <input type={"text"} id={"user-name"} className={"form-control"} value={data.userName}/>
      </div>
      <div className={"my-3"}>
        <label for={"user-tel"} className={"form-label"}>전화번호 : </label>
        <input type={"tel"} id={"user-tel"} className={"form-control"} value={userTel}/>
      </div>
      <div className={"my-3"}>
        <label for={"user-email"} className={"form-label"}>이메일 : </label>
        <input type={"email"} id={"user-email"} className={"form-control"} value={userEmail}/>
      </div>
    </div>
  );
}

export default Profile;
  • ProfileList.jsx
// folder1/ProfileList.jsx

import React from "react";
import Profile from "./Profile";

/*
props : 자바스크립트 컴포넌트 간의 데이터 전달을 위해서 사용하는 자바스크립트 객체, 읽기 전용
        부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달 시 사용
        부모 컴포넌트에서 자식 컴포넌트를 호출하여 사용 시 속성을 사용하여 데이터를 전달
        부모 컴포넌트에서 사용한 속성명이 자식 컴포넌트의 props 객체에 담겨서 전달이 됨
        해당 속성명을 자식 컴포넌트에서 그대로 사용함
*/

function ProfileList() {
  return (
    <div className={"row"}>
      <div className={"col-sm-6 mx-auto"}>
        <Profile userId={"test1"} userName={"테스터1"} userTel={"01012345678"} userEmail={"test1@bitc.co.kr"}/>
        <Profile userId={"test2"} userName={"테스터2"} userTel={"01098765432"} userEmail={"test2@bitc.co.kr"}/>
      </div>
    </div>
  );
}

export default ProfileList;


props 이용해서 게시판 만들어보기

App3.jsx

import React from "react";
import ProfileList from "./folder1/ProfileList";
import BoardList from "./folder1/BoardList";

function App3() {
  return(
    <div>
      <ProfileList />
      <br/>
      <BoardList/>
    </div>
  );
}

export default App3;

BoardList.jsx

// folder/BoardList.jsx

import React from "react";
import BoardItem from "./BoardItem";

const boardItemList = [
  {boardIdx: 100}, {boardTitle: "게시판 100번 글 제목"}, {boardUserId: "test1"}, {boardCreateDate: "2023-01-03 12:40:40"},
  {boardIdx: 101}, {boardTitle: "게시판 101번 글 제목"}, {boardUserId: "test2"}, {boardCreateDate: "2023-01-03 12:41:40"},
  {boardIdx: 102}, {boardTitle: "게시판 102번 글 제목"}, {boardUserId: "test3"}, {boardCreateDate: "2023-01-03 12:42:40"},
]


function BoardList() {
  return (
    <div className={"container mx-auto"}>
      <table className={"table table-hover table-striped"}>
        <thead>
          <tr>
            <th>글 번호</th>
            <th>글 제목</th>
            <th>사용자</th>
            <th>등록 시간</th>
          </tr>
        </thead>
        <tbody>
          <BoardItem idx={"100"} title={"테스트 제목100"} userId={"test1"} createDt={"2023-01-03 12:50:00"}/>
          <BoardItem idx={"101"} title={"테스트 제목101"} userId={"test2"} createDt={"2023-01-04 12:50:00"}/>
          <BoardItem idx={"102"} title={"테스트 제목102"} userId={"test3"} createDt={"2023-01-05 12:50:00"}/>
        </tbody>
      </table>
    </div>
  );
}

export default BoardList;

BoardItem.jsx

// folder/BoardItem.jsx

import React from "react";

function BoardItem({idx, title, userId, createDt}) {
  return(
    <tr>
      <td>{idx}</td>
      <td>{title}</td>
      <td>{userId}</td>
      <td>{createDt}</td>
    </tr>
  );
}

export default BoardItem;

기본적인 것 완성


  • BoardList.jsx
// folder/BoardList.jsx

import React from "react";
import BoardItem from "./BoardItem";

const boardItemList = [
  {boardIdx: 100, boardTitle: "게시판 100번 글 제목", boardUserId: "test1", boardCreateDate: "2023-01-03 12:40:40"},
  {boardIdx: 101, boardTitle: "게시판 101번 글 제목", boardUserId: "test2", boardCreateDate: "2023-01-03 12:41:40"},
  {boardIdx: 102, boardTitle: "게시판 102번 글 제목", boardUserId: "test3", boardCreateDate: "2023-01-03 12:42:40"},
]


function BoardList() {
  // boardItemList.map((item) => {
  //   return <BoardItem idx={item.boardIdx} title={item.boardTitle} userId={item.boardUserId} createDt={item.boardCreateDate}/>
  // });
  return (
    <div className={"container mx-auto"}>
      <table className={"table table-hover table-striped"}>
        <thead>
          <tr>
            <th>글 번호</th>
            <th>글 제목</th>
            <th>사용자</th>
            <th>등록 시간</th>
          </tr>
        </thead>
        <tbody>
          {/* ----------------------- 아래 코드 주석 -> 위 코드로 바꿔서 줄일 수 있음! ----------------------- */}
          {/*<BoardItem idx={"100"} title={"테스트 제목100"} userId={"test1"} createDt={"2023-01-03 12:50:00"}/>*/}
          {/*<BoardItem idx={"101"} title={"테스트 제목101"} userId={"test2"} createDt={"2023-01-04 12:50:00"}/>*/}
          {/*<BoardItem idx={"102"} title={"테스트 제목102"} userId={"test3"} createDt={"2023-01-05 12:50:00"}/>*/}

          {boardItemList.map(
            (item) => {
              return <BoardItem idx={item.boardIdx} title={item.boardTitle} userId={item.boardUserId} createDt={item.boardCreateDate}/>
            })}
        </tbody>
      </table>
      <BoardItem/>
    </div>
  );
}

export default BoardList;

사이트 따라 만들기

https://www.w3schools.com/w3css/tryw3css_templates_gourmet_catering.htm
https://www.w3schools.com/w3css/tryw3css_templates_gourmet_catering.htm

0개의 댓글