HTML into React

LSA·2022년 3월 13일
2

이걸해냄

목록 보기
4/8
post-thumbnail

본격적으로 React 경험담을 써보려 합니다.
혹시 요 글을 읽고 CRA를 설치하셨나요? 혹은 이미 CRA가 설치되셨나요?
축하합니다!이미 React가 설치되었어요!

React를 설치하는 방법은 공식 문서에도 여러 방법이 표기되어있지만, 저는 CRA를 통해 설치한 방법을 썼을 뿐입니다.

JSX 문법

리액트는 jsx라는 문법을 이용하고 있습니다.
한마디로 자바스크립트와 html을 동시에 적을 수 있는 문법인데, 이런게 가능합니다.

let h1 = <h1>h1입니다.</h1>;

잘 체감이 안됩니다. 자바스크립트에서도 저 정도는 충분히 할 수 있어요.

function MakeForm(){
 return (
   <section className="login-form">
                <h2 className="hidden">로그인 폼</h2>
                    <div className="input-box">
                        <input id="inputId" type="text" className="input-default" placeholder="전화번호, 사용자 이름 또는 이메일" />
                    </div>
                    <div className="input-box">
                        <input id="inputPw" type="password" className="input-default" placeholder="비밀번호" />
                    </div>
                    <button type='button' id="loginBtn" className="btn primary" onClick = {goUrl} >로그인</button>

                    <div className="form-end">
                        <span className="inline-link">비밀번호를 잊으셨나요?</span>
                    </div>
 </section>
 );
}

그럼 함수에다 태그로 이루어진 덩어리 자체를 때려박는 짓은요?
가능합니다.
물론 이것도 선언만 한다고 되는게 아니고, 라이브러리의 자체 문법과 규칙을 아주 잘 따라주어야 가능합니다. 제이쿼리를 써 보신 분들은 조금 공감이 가실지도..
공식 문서의 장점 자랑에 현혹되지 맙시다.

리액트 공식 문서만 보고 자신있게 코드를 변경하려 한 나

HTML을 옮겨보자

이것저것 설명하기보다, 그냥 제가 로그인 페이지를 jsx로 변환하는 과정을 같이 봅시다.

1번 줄부터의 전문입니다.이 코드들은 리액트 프로젝트 내의 public/index.html로 옮겨질텐데..
저기서 <div id="root"></div>가 보이시나요?
저 아래로 다 들어갈겁니다.

01. JS/JSX 파일 만들기

01-1. 컴포넌트 선언하기

우리는 리액트를 쓰는 순간부터,html페이지가 아니라 javascript로 페이지를 만들 겁니다.
먼저 login.js(혹은 login.jsx)를 만들어주세요.

리액트를 사용하는 페이지의 경우, 먼저 react에서 컴포넌트로 변환시켜줄 수 있는 함수 React를 불러와야 합니다.기존의 제이쿼리같은 라이브러리를 쓸때 헤드에 script로 연결해준 것처럼요.

import React from 'react';

이제 그 밑은 함수가 선언되어 있습니다.그런데 형태가 뭔가 요상해요.

function Login(){ //컴포넌트 이름은 반드시 대문자로 시작되는 PascalCase
   return (/* 작성할 HTML 코드*/ );
}

이게 바로 우리의 구조를 컴포넌트화 시켜줄 함수입니다.
물론,저 코드만으로는 컴포넌트가 출력되지 않아요.

밑에 export default Login; 이 명령어가 있어야 비로소 출력됩니다.

function Login(){ //컴포넌트 이름은 반드시 대문자로 시작되는 PascalCase
   return (/* 작성할 HTML 코드*/ );
}
export default Login;

그럼 저 return부분에다가 html을 넣어볼게요.

body의 바로 아래에서부터 script직전까지 싸그리 긁어옴

전부 집어넣었습니다.
다만, 원래 HTML 코드에서 body 태그에 입혀졌던 class .gray-body는 다른 <div> 로 변환하여 감싸줘야 합니다. 왜냐하면 저 컴포넌트가 출력될 곳에는 이미 body가 존재하니까요.
여기서 끝인가요? 아니요.

01-2. 파일 구조 파악하기(03.14 추가내용)

CRA를 깔면 큰 파일 구조는 이렇게 되어있습니다.

public 폴더와 src 폴더로 나뉘어있는데

  • public은 최종으로 출력될 폴더= index.html이나 img등이 들어있음
  • src는 public에서 끌어올 폴더 = index.js등의 컴포넌트,css 들이 들어있음
  1. index.js<Component/>라는 컴포넌트를 포함하고있다.(Component.js를 끌어온다는 것과 같음)
  2. Component.js<Login/>이라는 컴포넌트를 포함하고 있다.(Login.js를 끌어온다는 것과 같음)
  3. 최종적으로 작성할 코드는 Login.js에서 이루어집니다.

이렇게 폴더와 파일의 상관관계를 잘 알아야 어떤 파일을 어디에 import시킬지 구별이 명확해집니다!

02. JSX 문법에 맞춰 작성하기

02-1. 주석의 형태

10번째,24번째 줄에서의 주석이 보이나요? 저 주석은 html에서나 먹히는 주석 타입이므로 그대로 쓰면 출력되지 않습니다.리액트에서의 주석 처리는 {/* */} 형태입니다.

function Login(){ //컴포넌트 이름은 반드시 대문자로 시작되는 PascalCase
   return (
   <div class="gray-body">
         <div class="wrap-login">
         <section class="login-section">
               <h2 class="hidden">로그인 폼</h2>
               <h1 class="webucks-logo big-logo">webucks</h1>
               {/*form start*/}
               <form class="login-form">
                  <div class="input-box">
                     <input id="inputId" type="text" class="input-default" placeholder="전화번호, 사용자 이름 또는 이메일" />
                  </div>
                  <div class="input-box">
                     <input id="inputPw" type="password" class="input-default" placeholder="비밀번호" />
                  </div>
                  <button type='button' id="loginBtn" class="btn primary" disabled>로그인</button>

                  <div class="form-end">
                     <a class="inline-link" href="$">비밀번호를 잊으셨나요?</a>
                  </div>
               </form>
              {/*form end*/}
         </section>
      </div>
    </div>
    );
}

변경하면 이렇게 되겠죠!

02-2. class의 형태

물론 class도 저렇게 쓰다간 큰일납니다.리액트에서는 className이라고 class를 지칭합니다.
전부 바꿔주면 이렇게 됩니다.

function Login(){ //컴포넌트 이름은 반드시 대문자로 시작되는 PascalCase
   return (
   <div className="gray-body">
         <div className="wrap-login">
         <section className="login-section">
               <h2 className="hidden">로그인 폼</h2>
               <h1 className="webucks-logo big-logo">webucks</h1>
               {/*form start*/}
               <form className="login-form">
                  <div className="input-box">
                     <input id="inputId" type="text" className="input-default" placeholder="전화번호, 사용자 이름 또는 이메일" />
                  </div>
                  <div className="input-box">
                     <input id="inputPw" type="password" className="input-default" placeholder="비밀번호" />
                  </div>
                  <button type='button' id="loginBtn" className="btn primary" disabled>로그인</button>

                  <div className="form-end">
                     <a className="inline-link" href="$">비밀번호를 잊으셨나요?</a>
                  </div>
               </form>
              {/*form end*/}
         </section>
      </div>
    </div>
    );
}

02-3. a태그의 형태

react에서는 <a>태그가 없습니다. 넣으면 큰일납니다.(그냥 출력을 못해서 에러내는 정도..)
<a>태그를 다른 인라인 태그로 바꿔주면 이렇게 됩니다.

 <div className="form-end">
      <span className="inline-link">비밀번호를 잊으셨나요?</span>
 </div>

02-4. return 되는 컴포넌트의 형태

한가지 중요한 것은,이렇게 출력되는 컴포넌트는 전부 하나의 태그가 한번 감싸주어야 한다는 겁니다.

return (
	<ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
 	</ul>
)

돼요!

return (
	<div></div>
    <span></span>
)

안돼요!

제가 위에서 .gray-body클래스를 준 div로 한번 감싸준 것도 같은 이유에서입니다.

02-5. export default는 한 번만

그리고 맨 마지막줄에 쓰인 export default Login;같은 경우, default 값으로 이 컴포넌트를 내보낸다는 뜻이기 때문에 겹쳐서 쓸 수 없습니다.

export default Login;
export default Login2;

이렇게 쓰면 에러가 난다는 뜻이죠. 그럼 한 문서에 한 컴포넌트밖에 출력 못하는거에요?
아닙니다.
우리는 그냥 export {Login2} 이런 식으로 중괄호로 감싸준 이름을 export 해주면 됩니다.
export로 컴포넌트를 내보내는 다양한 방법은 아래 블로그를 참고해주세요.
https://lily-im.tistory.com/21

어쨌든 한 페이지에 여러 컴포넌트를 출력할수는 있지만, 유지보수를 위해 웬만하면 컴포넌트를 따로 분리해주는게 낫다고 생각합니다.

03. 자바스크립트처럼 이벤트 연결해주기

자바스크립트로 작동하는 문서인만큼, 정말 자바스크립트를 안에다가 같이 넣어줘도 됩니다.
버튼을 누르면 다른 페이지로 간다고 할 거에요. 먼저 button 태그에 onClick 이벤트를 넣어주고, 함수의 이름은 goUrl()이라고 해봅시다.

<button type='button' id="loginBtn" className="btn primary">로그인</button>

<button type='button' id="loginBtn" className="btn primary" onClick = {goUrl} >로그인</button>

저렇게 쓰면 끝인가요?
간단하네요!

물론 저 기능을 쓰려면, react-router-dom이라는 다른 라이브러리가 필요합니다.
react가 붙었긴 하지만 다른 집 친구입니다.

react-router-dom에 대해선 나중에 다시 자세히 쓰겠습니다.
어쨌든,react-router-dom의 함수 useNavigate 를 끌어올겁니다.그리고 return 명령어 위에다 함수를 추가할거에요.

 //list 페이지로 이동하는 goUrl함수
    const navigate = useNavigate();
    const goUrl = () => {
        navigate('/list');
    };

이 js 파일을 터미널에서 npm start로 구동해볼게요.

04. 완료된 코드와 화면 구동


import './Login.scss';
import { useNavigate } from 'react-router-dom';


function Login(){
    
    const navigate = useNavigate();
    const goUrl = () => {
        navigate('/list');
    };
    return (
        <div className="gray-body">
            <div className="wrap-login">
            <article className="login-section">
                <h2 className="hidden">로그인 박스</h2>
                <h1 className="webucks-logo big-logo">webucks</h1>
            
                <section className="login-form">
                <h2 className="hidden">로그인 폼</h2>
                    <div className="input-box">
                        <input id="inputId" type="text" className="input-default" placeholder="전화번호, 사용자 이름 또는 이메일" />
                    </div>
                    <div className="input-box">
                        <input id="inputPw" type="password" className="input-default" placeholder="비밀번호" />
                    </div>
                    <button type='button' id="loginBtn" className="btn primary" onClick = {goUrl} >로그인</button>

                    <div className="form-end">
                        <span className="inline-link">비밀번호를 잊으셨나요?</span>
                    </div>
                </section>
                
            </article>
        </div>
    </div>
    );
}


export default Login;


잘 보여집니다!!

profile
진짜 간단하게 작성한 TIL 블로그

0개의 댓글