React

POFO 클론코딩 -> React로 옮겨보기 실습

지난번 POFO 클론코딩 페이지를 HTML , CSS , JavaScript로 만들었고 그것을 토대로 ReactComponent화 시켜서 옮기는지 간단하게 알아보는 시간이다.


<body> 의 구성

<body>에 기본적으로 <div id="root"></div>가 들어가고 <script type="text/babel"></script> 안에 Component를 생성하여 넣어준다.

  • WrapComponent 최상위 컴포넌트
    안에
    • HeaderComponent
    • MainComponent
      안에
      • SectionComponent
    • FooterComponent

#use strict 란?

es5 부터 지원하는 use strict모드는 암묵적인 sloppy mode를 해제하고 엄격모드 use strict를 사용하는 모드이다.

🕵️‍♀️use strict 사용으로 발생하는 제약 조건들

  • 전역 변수를 허용하지 않으며, 전역 변수 선언시 오류가 발생합니다.
  • 변수 이름 선언 및 사용시 "var"가 누락되면 오류가 발생합니다.
  • 값 할당 실패는 오류가 발생합니다 (NaN = 1;).
  • 삭제할 수없는 속성을 삭제하려고 하면 (Object.prototype 삭제) 오류가 발생합니다.
  • 읽기 전용 속성에 쓰기를 하려고 하면 오류가 발생합니다.
  • 객체 리터럴의 모든 속성 이름은 고유해야합니다. (var x = {x1 : "1", x1 : "2"}).
  • 함수의 파라메터는 고유해야 합니다. (function calc (x, x) {}와 같이 같은 파라미터 이름 중복 사용 금지).
  • 8 진수 구문과 8진수 이스케이프 표현 금지(var a = 010; 과 같은 8진수 표현 사용 금지)
  • with 키워드 금지
  • 'eval', 'agruments'는 예약어로 변수명으로 사용할 수 없음.(var eval = 1;)
  • 변수를 생성하는 eval()은 보안상 사용할 수 없습니다.(eval ("var x = 2");)
  • 변수 이름과 함수 이름 삭제 금지 (var a = 1; delete a;)
  • arguments.callee 미지원. arguments.callee 속성은 이름이 없는 익명 함수(anonymous function)를 선언해서 사용할 때 실행 중인 함수 안에서 함수 자신을 참조하기 위해서 사용합니다. 재귀 호출 방식으로 자신을 호출하는 방식은 잠재적으로 참조 오류를 발생시킬 수 있습니다.

[출처] https://blogpack.tistory.com/972


다시 이어서 수업시간에 위에서 배운 use strict모드로 컴포넌트를 생성하고 넣었다.
먼저 크게 구성을 하자면 최상위 컴포넌트 Header , Main , Footer 예 : WrapComponent 를 만들어 body에 있는 <div id="root"/>에 넣어주고 구분하고 하위 컴포넌트로 세부적으로 만들어 넣어준다.

1. 최상위 컴포넌트 : WrapComponent

 class WrapComponent extends React.Component { 
            render() {
                return (
                    <div id="Wrap">
                        <HeaderComponent/>
                        <MainComponent/>
                        <FooterComponent/>
                    </div>
                );
            }
        }

위 코드와 같이 클래스형 컴포넌트를 생성하고 최상위 컴포넌트를 만든다. 이름은 WrapComponent라고 짓고 컴포넌트를 생성하면 extends 옆에 Component 로 적혀있는데 앞에 React를 적어서 React.Component로 바꿔준다.


[궁금] React 의 render 함수란?

리액트는 가상돔(Virtual DOM)을 사용합니다.
가상돔을 단순히 설명하면, 아직 화면에 나타나지 않고 프로그램(메모리) 상에만 만들어져 있는 html 이라고 생각하면 쉽습니다.
그렇게 프로그램(메모리)상에만 만들어져 있는 가상돔을 실제로 화면에 나타내야 눈으로 볼 수 있겠죠.
가상돔(Virtual DOM)을 실제 DOM 으로 바꿔야 하는것입니다.
이렇게 가상DOM을 실제DOM 으로 변경해주는 일을 render() 함수가 합니다.


이렇게 가상돔을 사용하여 실제 DOM을 바꿔주는 render함수 안에 return문을 사용하여

 <div id="Wrap">
   <HeaderComponent/>
   <MainComponent/>
   <FooterComponent/>
 </div>

Wrap안에 하위컴포넌트를 담아둔다.

제일 하단에 ReactDOMrender를 시켜주는 것도 잊지 않아야 함!

ReactDOM.render(
                <WrapComponent/>,
                document.getElementById('root')
            );

2. 헤더영역 : HeaderComponent 의 구성

class HeaderComponent extends React.Component {
                render() {
                    return (
						👉<Header 부분추가>👈	
  					)
  				}
  			}

HeaderComponent를 생성하였다. 동일하게 extends 옆에 React.Component로 수정하고 return문 안에 헤더영역 HTML을 넣어준다. *(저번에 한 POFO 클론코딩을 바탕으로 해보는 것이기 때문에 POFO 페이지의 헤더부분 HTML를 복사하여 붙여넣었다.)

붙여넣은 다음이 문제이다. JSX에 맞춰 작성해야 하므로
HTML에서 작성했던 classclassName으로
HTML의 단일태그 (예 : <img> , <br> ) 태그를 모두 /닫아 주어야 한다.

일단 단일태그는 어쩔 수 없다. 하나하나 찾아가며 /닫아 주어야 하고, *(나중에 혹시라도 방법을 알게된다면 작성하겠다)
classVScode(Visual Studio Code) 에서 찾기 단축키를 누른다 ctrl + f를 하면 아래와 같은 창이 뜬다.

예시 처럼 찾을단어는 class로 쓰지만 끝에 =를 썼다. 왜냐면 다른 class가 수정될 수 있기 때문이다. (클래스형 컴포넌트를 사용하므로 클래스 컴포넌트의 class도 바뀔 수 있기 때문) class=를 찾아서 className=으로 모두 바꿔준다. (No results 밑에 두개의 아이콘이 있는데 왼쪽은 하나만 바꾸기 오른쪽은 모두 바꾸기이다.)


3. 메인영역 : MainComponent 의 구성

class MainComponent extends React.Component {
                render() {
                    return (
                        <div id="main">
                            <Section1Component/>
                            <Section2Component/>
                            <Section3Component/>
                            <Section4Component/>
                        </div>
                    );
                }
            }

Main 영역의 Component의 구성이다. 앞서 컴포넌트를 큰 덩어리로 잡고 세부적인 컴포넌트를 넣어주는게 Main영역에서 넣어준다 (현재는 메인이 제일 복잡하고 세부적으로 나누어져 있기 때문)
return문 안에 세부적인 section들을 담아준다.


4. 섹션영역 : Section{$}Component 의 구성

Main 컴포넌트를 보면 (현재 내가 하고 있는 POFO의 섹션은 총 4개이다) 그러므로 1~4 섹션컴포넌트가 차례대로 넣어져있고,
Section1Component이름으로 클래스 컴포넌트를 생성하여 넣어준다.

class Section1Component extends React.Component {
                    render() {
                        return(
  							👉<Section1 부분추가>👈	
  						)
  					}
  				}

이렇게 예제는 Section1Component를 만들었지만 1~4번 섹션도 마찬가지로 똑같이 이어서 작성하여 만들면 된다.


5. 풋터영역 : FooterComponent 의 구성

class FooterComponent extends React.Component {
                    render() {
                        return(
  							👉<Footer 부분추가>👈	
  						)
  					}

동일하다. Footer부분을 return문 안에 넣으면 된다.

이렇게 까지 헤더 , 메인 , 풋터 를 컴포넌트 생성하여 넣어주었다.
다시 한번 마지막에 ReactDOM.render가 잘 되었는지 확인한다.

 ReactDOM.render(
 	<WrapComponent/>,
 	document.getElementById('root')
 );

6. JavaScript / JQuery 링크 & 사용

컴포넌트를 담는 script태그 다음 script에 아래와 같이 링크하여 불러준다.

<script type="text/babel" src="./js/script(real).js"></script>


7. 리액트 전체 코드 구성

<body>
   <div id="root"></div>
   <script type="text/babel">
       'use strict'
       class WrapComponent extends React.Component {
           render() {
               return (
                   <div id="Wrap">
                       👉<HeaderComponent/>👈
                       👉<MainComponent/>👈
                       👉<FooterComponent/>👈
                   </div>
               );
           }
       }
           class HeaderComponent extends React.Component {
               render() {
                   return (
                       /* 👉<header></header>👈 */
                   );
               }
           }
           class MainComponent extends React.Component {
               render() {
                   return (
                       <div id="main">
                           👉<Section1Component/>👈
                           👉<Section2Component/>👈
                           👉<Section3Component/>👈
                           👉<Section4Component/>👈
                       </div>
                   );
               }
           }
               class Section1Component extends React.Component {
                   render() {
                       return (
                           /* 👉<section></section>👈 */
                       );
                   }
               }
               class Section2Component extends React.Component {
                   render() {
                       return (
                           /* 👉<section></section>👈 */
                       );
                   }
               }
               class Section3Component extends React.Component {
                   render() {
                       return (
                           /* 👉<section></section>👈 */
                       );
                   }
               }
               class Section4Component extends React.Component {
                   render() {
                       return (
                           /* 👉<section></section>👈 */
                       );
                   }
               }
           class FooterComponent extends React.Component {
               render() {
                   return (
                       /* 👉<footer></footer>👈 */
                   );
               }
           }
           ReactDOM.render(
               👉<WrapComponent/>,👈
               document.getElementById('root')
           );
	</script>
   <script type="text/babel" src="./js/script(real).js"></script>
</body>

전체적인 코드구성이다 전부 클래스 컴포넌트를 사용하였고, 최상위 컴포넌트root에 넣는것과 Main컴포넌트안에 각 SectionComponent를 잘 넣어주는 것이다.


결과는 아래와 같이 되었다.

0개의 댓글