[React]

리액트 명령어

 

# (최초1번) npm install -g create-react-app

# react 프로젝트 만들기 : 
npx create-react-app 프로젝트명

# react 프로젝트 실행하기 :
cd 프로젝트명 (프로젝트명 폴더로 들어가기)
npm start    (react 서버 가동 명령어))

# react 프로젝트 중단하기 : 
vscode 터미널 창에서 : ctrl + c (2번이상 타이핑하고 엔터)

 

리액트 특징

 

# React(페이스북, 점유율1위) / Vue(개인, 구글퇴사) / Angular js(구글 x)

# React / Vue : SPA(Single Page Application) 개발
#  (html 1장으로 개발 : 메뉴: 홈/로그인/회원가입 페이지 등)
#   (각 페이지가 js 코딩되어 -> html 로 바뀜)

 

 

 

 

npx create-react-app hello-world

입력 후 성공 시 뜨는 화면

cd hello-world

npm start 서버 시작 명령어

 

입력 후 성공시 뜨는 화면

리액트 서버 실행

서버 중단 명령어 ctrl + c

y 누르거나 ctrl + c 두번 누르기

App.js의 div태그에서 내용 바꾸면 화면도 바뀜

확장 프로그램 추가 설치

 

React develop tool 설치

1) Auto Import / 2) ES7+ React/Redux / 3) TODO Highlight 플러그인 설치

크롬 웹 스토어 접속

https://chrome.google.com/webstore/category/extensions?hl=ko 

 

Chrome 웹 스토어

Chrome에 사용할 유용한 앱, 게임, 확장 프로그램 및 테마를 찾아보세요.

chrome.google.com

 

확장 프로그램 관리 들어가서

파일 URL에 대한 액세스 허용 체크

리액트 디버깅 정보 확인

터미널 닫을 때는 휴지통 아이콘 클릭

 

001

 

App.js

(원하는 js 주석해제)

// 리액트 주소 : http://localhost:3000
// http://(프로토콜),
// localhost(인터넷주소 예)naver.com ) : 개인pc 인터넷주소
// 3000 : 포트번호(0 ~ 90000) , :80(이것만 생략)
// App.js : 리액트의 1st 페이지(사이트 home 페이지)
// => 리액트 서버가 가동되고 처음으로 실행되는 페이지(js)
// 리액트 페이지(js) : 컴포넌트(==페이지)
// 사용법 :
// function 컴포넌트명() {
      // return {
      //    <div>내용</div>
      // }
// }      

import logo from './logo.svg';
import './App.css';
// 자식 컴포넌트(페이지) import
// import Home from "./components/Home.js";
import Home from "./components/Home.js"
// 자식 컴포넌트 import
import Header from "./components/Header";
import Footer from './components/Footer';
import B_Home2 from './components/B_Home2';
import C_Exam from './components/C_Exam';
import D_ImportComp from './components/D_ImportComp';

// 최상위 부모 컴포넌트 : App(App.js)
// 자식 컴포넌트 : Home(Home.js)
function App() {
  return (
    <div className="App">
      <div>
        <h1>Start React 200!</h1>
        <p>HTML 적용하기</p>
      </div>

      {/* 머리말 */}
      {/* <Header></Header> */}

      {/* 주석 : ctrl + / */}
      {/* Home.js 컴포넌트 태그 */}
      {/* 본문 */}
      {/* <Home></Home> */}
      {/* <B_Home2></B_Home2> */}
      {/* TODO: 연습문제 */}
      {/* <C_Exam></C_Exam> */}

      {/* <D_ImportComp></D_ImportComp> */}


      {/* TODO: 꼬리말 컴포넌트 정의해서 넣으세요
          이름 : Footer
      */}
      <Footer></Footer>
    </div>
  );
}

export default App;

Home.js

리액트 페이지(컴포넌트) 단축키 rfce

// 리액트 페이지(컴포넌트) 단축키 : rfce
// TODO: 모든 자료형 출력해보기(출력되는것/안되는것)
// 자식 컴포넌트
import React from 'react'

function Home() {

  // TODO: 변수를 정의하는 곳 : 여기
  let array = ["a", "b", "c"]; // 일반변수
  // 리액트 특징 : 변수값 + html 태그를 같이 사용이 가능함(JSX 표현식)
  let input = <b>문자열 출력되나요?</b>;

  // TODO: 함수를 정의하는 곳 : 여기
  // 함수선언식 : function 함수명(){}
  // 함수표현식 : let 함수명 = function(){};
  // 화살표함수 : let 함수명 = () => {}
  // 화살표함수 단축키 : nfn
  const testFunc = () => {
      return "함수입니다.";
   }

  //  클릭 이벤트 함수
  // nfn
  const myClick = () => {
    alert("클릭했어요!!!");
   }

  // TODO: html 태그 + JSX 표현식({}) : return 안에 코딩함
  // TODO: 웹브라우저 화면에 표시되는 영역
  return (
    <div>
      {/* 주석 : ctrl + / */}
      {/* 1) 문자열 출력 : O */}
      {/* 사용법 : {"문자열"} */}
      {"문자열 출력되나요!!!"}
      <br/>
      {input}
      <br/>
      {<b>이것도 출력될까요?</b>}
      <br/>

      {/* 2) 숫자 출력 : O */}
      {1 * 2 + 3 - 2}
      <br/>
     
      {/* 3) 문자열 붙이기 : + */}
      {"abc" + "가나다"}
      <br/>

      {/* 4) JSX 표현식 : {<태그>{문자열}</태그>} : O */}
      {<b>{"안녕하세요"}</b>}
      <br/>

      {/* 5) 배열 출력 : O */}
      {["가", "나", "다"]}
      <br/>
      {[1,2,3]}
      <br/>
      {array}
      <br/>

      {/* 6) 함수 출력 : */}
      {/* 함수의 사용 : 함수명() : O */}
      {testFunc() + " 이것도 될까요?"}
      <br/>
      {/* 7) 3항 연산자 : 조건식(축약형) : O */}
      {/* 사용법 : (조건식==true)? 참 : 거짓; */}
      {true? "true" : "false"}
      <br/>
      {false? "true" : "false"}
      <br/>

      {/* 8) html 태그 속성의 값으로 {} 넣어보기 :  */}
      <a href={"http://www.naver.com"}>네이버</a>
      <br/>
      <button onClick={myClick}>클릭하세요</button>
      <br/>

      {/* 9) 자바스크립트 내장 함수 */}
      {console.log("이것도 출력될까요?")}
      <br/>
      {/* 오늘 요일(1 ~ 7) : new Date() */}
      {new Date().getDay()}
      <br/>
      {new Date().getFullYear() + "년"}
      <br/>
      {(new Date().getMonth()+1) + "월"}

      {/* ------------------------------------------- */}
      {/* 화면에 출력 안되는 것 */}
      {/* ------------------------------------------ */}
      {/* 10) 참/거짓(bool/boolean) : X */}
      {/* 해결책 : 참/거짓 -> 문자열 로 변경해서 출력 */}
      {true}

      {/* 11) 객체 출력 : x , 에러 발생 */}
      {/* 해결책 : 객체 -> 문자열 로 변경해서 출력 */}
      {/* {{name:"홍길동", email:"hong@naver.com"}} */}

      {/* 12) 조건문 : if문 : x */}
      {/* 해결책 : 3항 연산자 */}
      {/* {if(true) {return "true"}} */}

      {/* 13) 반복문 : for문 : x */}
      {/* 해결책 : map() 함수 가능 */}
      {/* {for(let i=1;i<2;i++){console.log("aaa")}} */}

    </div>
  )
}

export default Home

결과

B_Home2

// B_Home2.js : 자식
// rfce
// TODO: 화면 바인딩
import { useState } from "react";

function B_Home2() {
    // TODO: 변수를 정의하는 곳 : 여기
    // 최초 1번만 정상적으로 화면에 표시
    // 수정 -> 화면에 수정된 값이 보이지 않음
    let hello = "안녕하세요"; //  일반변수

    // 바인딩 변수 : 리액트에서는 화면에서 수정이 일어났을때 정상적으로
    //             보이게 만들어 주는 변수
    // 사용법 : let [변수명, 수정함수] = useState("초기값")
    let [element, setElement] = useState("안녕");

    // TODO : 함수 정의 : 여기
    // nfn
    // 화면 바인딩 없음 : 수정해서 화면에 나타나지 않음
    const myClick = () => {
        hello = "안녕하세요2";
     }

    // nfn
    // TODO: 화면 바인딩 있음 : 수정하면 화면에 나타남
    const myClick2 = () => {
        // 리액트의 수정함수
        setElement("안녕2");
     }

    // TODO: 웹브라우저 화면에 나오는 부분 : 아래
  return (
    <div>
        {hello}
        <button onClick={myClick}>클릭해보세요</button>
        <br/>
        {element}
        <button onClick={myClick2}>클릭해보세요2</button>
        <br/>
    </div>
  )
}

export default B_Home2

결과

클릭 후

C Exam

// C_Exam.js : 자식 컴포넌트
import { useState } from "react";
// rfce
// TODO: 연습문제
// TODO : 클릭시 아래 결과대로 코딩하세요
// TODO : 최초화면 : "안녕하세요"
// TODO : 결과 : "안녕"
// TODO: 1) 바인딩 변수 정의

function C_Exam() {
    // TODO: 변수 정의 : 여기
  // useState()
  // 바인딩 변수 : 리액트에서는 화면에서 수정이 일어났을때 정상적으로
  //             보이게 만들어 주는 변수
  // 사용법 : let [변수명, 수정함수] = useState("초기값")
  let [element, setElement] = useState("안녕하세요");

  // TODO: 2) myClick() 화살표 함수 : 안녕 으로 수정
  // nfn
  const myClick = () => {
    // 수정 함수 : "안녕"
    setElement("안녕");
  };
 
  return (
    <div>
      {element}
      <br />
      <button onClick={myClick}>문자열변경</button>
    </div>
  );
}

export default C_Exam;

결과

D ImportComp

css

/* D_ImportComp.css */
.dms01-h2 {
    color: white;
    background-color: black;
}

js

// D_ImportComp.js : 자식 컴포넌트
// TODO: 리액트 컴포넌트 디자인 적용하기 : css 파일 적용
// rfce
import React from 'react'
// css 파일 import
import "../assets/D_ImportComp.css";

function D_ImportComp() {

    // TODO: 화면에 보이는 부분
  return (
    <div>
        {/* class="" => className="" : 리액트에는 class 대신 사용함 */}
        <h2 className="dms01-h2">ImportComp</h2>
    </div>
  )
}

export default D_ImportComp

결과

002

App.js

// 이미지 import
// import logo from './logo.svg';
// App.css import (기본 : 중앙정렬)
import './App.css';
import A_Lifecycle from './pages/A_Lifecycle';
import B_Props from "./pages/B_Props";
import C_Exam from "./pages/C_Exam";
import D_Exam2 from './pages/D_Exam2';
import E_Exam3 from './pages/E_Exam3';
import F_Clock from './pages/F_Clock';

// TODO: 리액트에서 처음으로 실행되는 js (최상위 부모 컴포넌트)
// TODO: 웹브라우저 확인(주소창) : http://localhost:3000
function App() {
  // 변수/함수를 정의하는 부분

  // 화면에 보이는 부분 : return 안에 있는 html 태그 화면에 보임
  return (
    <div className="App">
      <h1>Start React 200!</h1>
      {/* 자식 컴포넌트 추가 */}
      {/* <A_Lifecycle></A_Lifecycle> */}
      {/* <B_Props prop_value="hong gil dong"></B_Props> */}
      {/* TODO: 연습문제 : 데이터 전달 */}
      {/* <C_Exam prop_value="From App" /> */}
      {/* 연습문제 2 */}
      <D_Exam2 />
      {/* 연습문제 3 */}
      {/* <E_Exam3 name="처음 만난 파이썬"
               numOfPage={300} /> */}
      {/* <E_Exam3 name="처음 만난 자바"
               numOfPage={500} /> */}
      {/* <F_Clock /> */}
    </div>
  );
}

export default App;

D exam

// D_Exam2.js : 연습문제
// rfce
// TODO: 아래 생명주기 함수 2개를 만들어서 출력하세요
// TODO: 1) 화면이 뜰때 아래의 결과가 콘솔에 출력됨(console.log)
// TODO: 결과 : mount call

// TODO: 2) tmpState2 라는 변수의 값이(true) 변경되면 콘솔에 출력됨(console.log)
// TODO:    버튼을 클릭하면 변수의 값이 변경됨
// TODO: 결과 : false
import React, { useEffect, useState } from "react";

function D_Exam2() {
  // TODO: 변수 (바인딩)
  // 사용법 : let [변수명, set변수명] = useState(초기값);
  let [tmpState2, setTmpState2] = useState(true);

  // TODO: 1) 생명 주기 함수(생성) : 출력 : mount call
  // TODO: 화면이 뜰때 자동 실행
  // 사용법 : useEffect(()=>{실행문}, []);
  useEffect(() => {
    console.log("mount call");
  }, []);

  // TODO: 2) 생명 주기 함수(수정) : tmpState2 : true -> false (콘솔에 출력)
  // 사용법 : useEffect(()=>{실행문}, [감시할변수명]);
  useEffect(() => {
    console.log(tmpState2); // 변수값 바뀌면 실행
  }, [tmpState2]);

  // TODO: 2-2) 클릭 이벤트 함수 정의
  // 화살표 함수 단축키 : nfn
  const handleClick = () => {
    // 수정함수 : setter 함수 호출 : 값 변경 : true -> false
    setTmpState2(false);
  };

  return (
    <div>
      <h2>[ THIS IS shouldComponentUpdate FUCNTION ]</h2>
      <button onClick={handleClick}>클릭</button>
    </div>
  );
}

export default D_Exam2;

F Clock

// F_Clock.js : 자식
// rfce
import React from 'react'

function F_Clock() {
    // 화면에 보이는 부분 : 아래 return
  return (
    <div>
        <h1>안녕, 리액트</h1>
        <h2>
            현재 시간 :
            {/* .toLocaleTimeString() : 국가별 현재 시간 출력 */}
            {new Date().toLocaleTimeString()}
        </h2>
    </div>
  )
}

export default F_Clock

결과

003

App.js

import A_Comment from "./pages/A_Comment";
import B_Comment_Exam from "./pages/B_Comment_Exam";
import C_Comment_Exam2 from "./pages/C_Comment_Exam2";
import D_CommentList from "./pages/D_CommentList";
import E_CommentList_Exam from "./pages/E_CommentList_Exam";
import F_CommentList_Exam2 from "./pages/F_CommentList_Exam2";

function App() {
  return (
    <div className="App">
      {/* 자식 컴포넌트 추가 */}
      <A_Comment />
      {/* <B_Comment_Exam /> */}
      {/* <C_Comment_Exam2 /> */}
      {/* <D_CommentList /> */}
      {/* <E_CommentList_Exam /> */}
      {/* <F_CommentList_Exam2 /> */}
    </div>
  );
}

export default App;

style.css

.App {
    text-align: center;
    font-size: 50px;
  }
 

Comment.css

.wrapper {
    margin: 8;
    padding: 8;
    display: "flex";
    flex-direction: "row";
    border: "1px solid grey";
    border-radius: 16;
};

.image {
    width: 50;
    height: 50;
    border-radius: 25;
};
.contentContainer {
    margin-left: 8;
    display: "flex";
    flex-direction: "column";
    justify-content: "center";
};
.nameText {
    color: "black";
    font-size: 16;
    font-weight: "bold";
};
.commentText {
    color: "black";
    font-size: 16;
};

A_Comment.js

// A_Comment.js : 자식
// rfce
import React from "react";
// Comment.css import
import "../assets/Comment.css";
import "../assets/styles.css";

import { useState } from "react";

function A_Comment() {
  // TODO: 변수/함수 정의 : 여기
  // 사용법 : let [변수, set변수] = useState(초기값);
  // set변수 : setter 함수 (변수 값 저장 용도 함수)
  // 화면 바인딩 용도 : useState() 함수 (훅(hook) 함수 : useXXX())
  let [name, setName] = useState("홍길동");
  let [comment, setComment] = useState("메모");

  return (
    <div className="wrapper">
      <div className="imageContainer">
        <img
          className="image"
        />
      </div>

      <div className="contentContainer">
        <span className="nameText">{name} </span>
        <span className="commentText">{comment} </span>
      </div>
    </div>
  );
}

export default A_Comment;

결과

C_Comment exam2.js

// C_Comment_Exam2.js : 자식(연습)
// rfce
import React, { useState } from 'react'
import "../assets/styles.css";

// TODO : useState 이용 4가지 변수 넣기, Comment_Exam2.css import
//        name="제목"
//        link="http://www.naver.com"
//         isUpdate=true
function C_Comment_Exam2() {
    // 힌트 : 변수/함수 정의
    let [img, setImg]
    let [name, setName] = useState("제목");
    let [link, setLink] = useState("http://www.naver.com");
    let [isUpdate, setIsUpdate] = useState(true);

  return (
    <div className="wrapper">
    {
      // TODO : image 는 img 태그의 src 에 넣고, link 주소는 a href 속성에 넣어서 출력하시요
      // TODO : isUpdate 가 true 이면 화면에 "true" 라고 출력하고, false 이면 "false"라고 출력하세요.
    }
    <div className="contentContainer">
      <span className="commentText">
        <img src={img} />{" "}
      </span>
      <br/>
      <span className="nameText">{name} </span>
      <span className="commentText">
        <a href={link}>{link} </a>
      </span>
      <span className="commentText">{isUpdate? "true":"false"} </span>
    </div>
  </div>
  )
}

export default C_Comment_Exam2

결과

D_CommentList.js

// D_CommentList.js : 자식
// TODO: 리액트의 반복문 : map() 함수 사용
// rfce
import React, {useState} from 'react'
import "../assets/styles.css";

function D_CommentList() {
    // 객체배열 : [{},{} ...] === JSON 문서 데이터 형태(인터넷 통신 거의 표준)
    // 프론트 <-(JSON 데이터)-> 벡엔트(DB 넣기)
    const initialComments = [
        {
            name: "이인제",
            comment: "안녕하세요, 소플입니다."
        },
        {
            name: "유재석",
            comment: "리액트, 재미있어요!!."
        },
        {
            name: "강민경",
            comment: "저도 리액트 배워보고 싶어요!!"
        },
    ];

    // TODO: 변수/함수 정의
    // useState() 함수 이용 변수 정의
    // 사용법 : let [변수명, set변수명] = useState(초기값)
    let [comments, setComments] = useState(initialComments);

    // HTML 태그 작성 부분 : return 부분
    // 사용법 : 배열변수.map((value, index(생략), array(생략))=>{반복문;});
    // value :배열의 값, index : 배열의 번호, array : 배열
    // TODO: map() 함수 : 배열변수.map(함수());
    // TODO: 용도 : for문 대신 사용하는 구문
    // TODO: 특징 : 배열변수의 크기(길이, 건수)만큼 자동으로 반복함 (함수())  
  return (
    <div>
        {
            comments.map((comment, index)=>{
                // 반복문 : JSX 표현식(js + html 섞어 쓸수 있음)
                return (
                    // TODO: 여기 : 반복 ?
                    <div className="wrapper" key={index}>
                    <div className="imageContainer">
                      <img
                        className="image"
                      />
                    </div>
       
                    <div className="contentContainer">
                      <span className="nameText">{comment.name}</span>
                      <span className="commentText">{comment.comment}</span>
                    </div>
                  </div>
                )
            })
        }
    </div>
  )
}

export default D_CommentList

결과

E_CommentList.exam

// CommentList_Exam.js
// TODO : 아래 데이터가 주어졌을때 화면에 출력하세요
import React, {useState} from "react";
import "../assets/styles.css";

function E_CommentList_Exam() {
  // TODO : 아래 데이터가 주어졌을때 화면에 출력하세요
  const initialComments = [
    {
      id: 1,
      title: "어떻게 배울 것인가",
      publisher: "비즈니스북스",
      author: "존 맥스웰",
      stock: 2,
    },
    {
      id: 2,
      title: "신경끄기의 기술",
      publisher: "갤리온",
      author: "마크 맨슨",
      stock: 0,
    },
    {
      id: 3,
      title: "부의 미래",
      publisher: "청림출판",
      author: "앨빈 토플러",
      stock: 5,
    },
    {
      id: 4,
      title: "기획자의 습관",
      publisher: "홍익출판사",
      author: "최장순",
      stock: 4,
    },
  ];

  // 변수/함수 정의
//   사용법 : let [] = useState() : 바인딩 변수(객체배열 === 배열)
  let [comments, setComments] = useState(initialComments);
  // -------------------------
  // html 태그
  //
  return (
    <div>
      {/* TODO :배열변수.map() 사용해서 반복문을
                작성하세요 */}
      {/* map 사용법 : 배열변수.map(()=>{return(태그)}) */}
      {/* comment : 배열의 값, index : 배열의 인덱스번호 */}
      {comments.map((comment, index) => {
        // TODO: 반복 : 4번 , 자동반복
        return (
          // html 태그(반복)
          <div>
            <div>
                <span>{comment.title}</span>&nbsp;
                <span>{comment.publisher}</span>&nbsp;
                <span>{comment.author}</span>&nbsp;
                <span>{comment.stock}</span>&nbsp;
            </div>
          </div>
        );
      })}
    </div>
  );
}

export default E_CommentList_Exam;

결과

F_CommentList_Exam2

// CommentList_Exam2.js
// TODO : 연습문제 아래 데이터를 반복문으로

import React,{useState} from "react";
import "../assets/styles.css";

function F_CommentList_Exam2() {
  // TODO : 연습문제 아래 데이터를 반복문으로
  //        출력하세요
  const initialWebtoons = [
    {
      name: "햄스터와 그녀",
      isUpdate: true,
    },
    {
      name: "프롬 스타",
      isUpdate: true,
    },
    {
      name: "위대한 로맨스",
      isUpdate: false,
    },
    {
      name: "빛나는 손을",
      isUpdate: false,
    },
  ];

  //   TODO: 변수 정의(useState())
  let [webtoons, setWebtoons] = useState(initialWebtoons);

  // 변수/함수 부분
  // -----------------------------------
  // html 부분

  return (
    <div>
      {/* html 아래 내용 반복문 수행 */}
      {/* 반복문 : 배열변수.map(()=>{return(태그)}) */}
      {webtoons.map((webtoon, index) => {
        return (
          // html 태그 추가(반복)
          <div className="wrapper" key={index}>
            <div className="contentContainer">
            <span className="commentText">
                <img src={webtoon.img} />{" "}
              </span>
              <br/>
              <span className="nameText">{webtoon.name}</span>
              <span className="commentText">
                <a href={webtoon.link}>{webtoon.link}</a>
              </span>
              <span className="commentText">
                {webtoon.isUpdate? "true": "false"}
              </span>
            </div>
          </div>
        );
      })}
    </div>
  );
}

export default F_CommentList_Exam2;

결과