Javascript도 잘 못하는 내가... ReactJS를 해야 할 때가 왔다.
예전에 인프런에서 ReactJs 강좌 동영상을 본 적이 있었는데..
너무 어려워서 한 번 듣고 따라해보고.. 포기했었다.

근데 이번에 정.....말 필요해져서 다시 들어볼까하고 인프런에서 강좌 찾고 있었는데,
니꼴라스(노마드코더) 동영상이 있는 것을 보았고 간혹 소셜에서 접했었던 사람이라 궁금해서 시청하기 시작했다.
주제도 어려워 보이지 않았고
처음에는 그냥 듣기만 했고, 다 보고 나서 따라 코딩했는데 정말 쉽고 좋았다.
돌 머리인 내가 어느정도 이해가 갔다면 확실히 니꼴라스가 잘 가르쳐준것 같다 + 자막도 최고

하지만 다들 알아야한다 v16.3 업데이트 전 내용이라 참고하고 다른 학습도 해야한다.


영상 주소
https://www.inflearn.com/course/reactjs-web/


ReactJS로 웹 서비스 만들기 학습 정리

※ 예제로 나오는 코드는 니꼴라스가 작성한 코드다.
create-react-app을 install 받아서 npm start

1. import

  import React from 'react';
  import ReactDOM from 'react-dom';
  import './index.css';
  import App from './App';
  import registerServiceWorker from './registerServiceWorker';
  //'react' 모듈에서 React 정의된 객체, 함수, 속성 등을 import 하겠다는 구문.
  // ReactDOM = 웹서비스, ReactNative = 모바일이라고 하더라.
  // 컴포넌트 최상단에 위치한다.

  // {Component}는 React.Component 클래스 속성을 import 하겠다는 것 같은데?
  import React, { Component } from 'react';
// ReactDOM.render 를 이용해서 app 컴포넌트를 엘리먼트 #root에 render시킨다.
ReactDOM.render(<app>, document.getElementById('root'));
+ 코드 플러그인 내부에 넣으니까 자꾸 <app>을 닫아주는 태그를 생성한다.....

2. JSX 문법을 쓴다.

Javascript + XML의 합성어
자바스크립트 내부에 HTML을 넣기 위해 사용된다.
JSX는 작성한 그대로 적용되는게 아니라 트랜스파일러를 통해 변환된다고 한다.
// <movie> {} className render() return() 같은 것들일까?
<div className={movies ? "App" : "App-loading"}>
{movies ? this._renderMovies() : 'loading...'}
</div>

3. class app extends React.Component

app은 컴포넌트 함수명임. 변경가능.
  // React.Component 클래스 속성을 상속해서 컴포넌트를 생성하는 방식
  // class 컴포넌트는 state가 존재하는 function이어서 state function이라고 한다.
  class App extends Component {
    ..........
  }

  // state가 존재하지 않는 function은 stateless function이라고 하며 기존의 자바스크립트 function을 말한다.
  // stateless function은 props만 있으며 return하기 위해 사용한다고 한다.
  function Movie({title, poster, genres, synopsis}){
    return(
     ..............
    )
  }
사용 이유에 따라 두 가지를 적절히 나누어 사용하라고 한다.

4. LifeCycle

v16.3으로 버전 업데이트가 되면서 니꼴라스 강의에서 나온 lifeCycle이 달라졌음을 알게되었다.

componentWillMount()
componentWillUpdate()
componentWillReceiveProps() 

세가지가 없어졌다. 
- 기존에 사용하던 것들을 대체하기 위해 메서드 앞에 prefix로 UNSAFE_를 붙이면 사용할 수 있다.
- UNSAFE_componentWillMount()

componentWillMount() 
여기서 하던 작업은
constructor(), componentDidMount를 사용한다고 한다.

componentWillUpdate()
여기서 하던 작업은
getSnapshotBeforeUpdate()를 사용한다고 한다.
getSnapshotBeforeUpdate(prevProps, prevState){
  if(prevState.value !== this.state.value){
    return ........ ; 
  }
}

componentWillReceiveProps() 
여기서 하던 작업은 
static getDerivedStateFromProps()로 대체 한다고 한다.
사용방법은 이런 식이라고 한다.
static getDerivedStateFromProps(nextProps, prevState){
  if(nextProps.value !== prevState.value){
   // value값이 다를 경우, return
   return  ........... ; 
  }
}

솔직히 바뀐건 아직 확실히 잘 모르겠다.
더 공부해야지..

render
remove
update

각각 다른 LifeCycle을 가진다.

-render
componentWillMount() > render() > componentDidMount()
render 전 > render > render 후
대충 활용 예시를 보면 api 호출, loading 애니메이션 등의 작업 > render > loading 애니메이션 제거

-remove
props, state 삭제 시에 한번만 사용된다.
componentWillUnmount()

-update
props, state가 업데이트 되면 실행된다.
componentWillReceiveProps() > shouldComponentUpdata() > componentWillUpdate() > render() > componentDidIpdate()
props를 새로 받았을 때 > 과거 state, props와 비교하여 다르다면 true 반환 > true일때 upadte 실행 > render > render 후
state가 update되면 componentWillReceiveProps() 단계는 건너 뛰고 shouldComponentUpdata()부터 실행된다.

5. props와 state 속성

props는 컴포넌트 mounting, updating 프로세스 시점에 값이 할당될 뿐, 내부에서 값을 변경할 수 없다.
상황에 따라 변경되어야 하는 값은 state를 이용해야한다.

state는 초기에 작성할 수도 있다.
  _getMovies = async () => {
      const movies = await this._callApi()
      // state는 직접적으로 변경해서 사용하면 안된다. (this.state.name = '스어'; 콘솔에러..)
      // this.state.movies = movies; (x)
  
      // setState() API를 통해 추가하거나 업데이트 해야 한다.
      this.setState({
        movies
      })
 }
state = 컴포넌트 내부에서 변경 가능
props = 컴포넌트 내부에서 변경 불가능

6. propTypes는 props type을 체크하여 validation해준다.

  
  // 사용하기 위해서는 propTypes 모듈을 install한 다음 import하여 사용해야 한다.
  import PropTypes from 'prop-types';
  
  function MoviePoster({poster,alt}){
    return(
      {alt}
    )
  }
  // props을 사용하는 .js 내부에 사용한다.
  MoviePoster.propTypes = {
    poster: PropTypes.string.isRequired,
    alt: PropTypes.string.isRequired
  }

7. Ajax

  
  // async는 비동기 형식으로 실행된다.
  _getMovies = async () => {
    // await은 함수가 종료되고 나서 진행한다는 의미, api 호출이 종료 되면 movies에 할당하고 다음 라인 실행
    const movies = await this._callApi()
    // this.state.movies = movies; (x)
    this.setState({
      movies
    })
  }
  _callApi = () => {
   // fetch에서 api를 호출
    return fetch('https://yts.am/api/v2/list_movies.json?sort_by=rating')
    .then(response => response.json()) // 데이터를 json 형식으로 변환
    .then(json => json.data.movies) // movies 데이터 return
    .catch(err => console.log(err))
  }

8. export

app은 컴포넌트 함수명임. 변경가능.
  
  // 다중 export
  export app1, app2, app3...;

  // *(asterisk / 별표) 는 파일 내 정의된 모든 객체, 함수, 속성 export
  export *;

  // default : 모듈의 기본 값, 파일 내 한 번만 호출 가능 
  export default App;
ReactJS
https://reactjs.org/docs/hello-world.html



목표! 

 1.도메인 등록

 2.호스팅 등록



도메인/호스팅 등록



워드프레스는 가입형과 설치형이 있습니다.

가입형은 네이버, 티스토리 블로그와 같이 운영이 되는 것이고 설치형은 워드프레스 소스코드를 설치하는 방식입니다.

(가입형 주소 : wordPress.com)


1 도메인 등록

도메인에 대해 사전을 검색해보면

'로마자로 나타낸 인터넷 사이트 주소. 숫자로만 구성된 아이피(IP) 주소의 단점을 보완하기 위해 사용함.  

예를 들어, 청와대의 도메인 이름은 www.bluehouse.go.kr 임.' 이라고 나옵니다. 

- 출처 : 구글 사전


위 사전에서도 적혀있듯이 더 간단히 말하면 집 주소 = 홈페이지 주소라고 생각하면 됩니다.

집 주소가 있어야 손님이 오겠죠? 


그래서 필수로 있어야 합니다.


포털에서 '도메인' 이라는 키워드만 검색해도 많은 도메인 회사 사이트가 검색됩니다.

여기서 제가 추천을 드릴 수는 없습니다.

왜냐하면 회사마다 서비스와 가격의 차이가 나기 때문입니다.

다양하기 때문에 여러군데 확인해보고 비교해보고 본인이 원하는 곳에서 하시길 바랍니다.


[도메인 구매 예시]

저는 닷홈(https://www.dothome.co.kr/)이라는 사이트에서 도메인 구매 예시를 보여드리겠습니다. 

1.닷홈에 들어가서 도메인 탭을 클릭합니다.

2.도메인 신청을 눌러 들어가면 도메인 검색하는 창이 나오는데, 본인이 사용하고자하는 주소를 적고 검색을 눌러줍니다.

  www.okayoon.com이라는 홈페이지 주소를 가지고 싶다면 'okayoon'을 적어주고 하단에 체크 박스에 .com을 체크해 줍니다. 

  (그 외 원하는 것을 체크해서 가격을 확인 할 수 있습니다.)


3. 검색버튼을 누르게 되면 가격을 확인 할 수 있습니다.

   작성한 도메인 확인이 되고, 구매 기간설정을 할 수 있습니다.

   신청하기 누르면 결제할 수 있습니다.

   혹시 내가 작성한 도메인 결과가 안나오면 사용하고 있는 도메인입니다.

   

4. 결제를 진행하게되면 도메인은 내 소유가 됩니다. (기간은 연장가능합니다.)




2 호스팅 등록


필수 작업인 호스팅 등록 작업입니다.


호스팅이 무어냐 하면... 내 홈페이지를 공유하기 위해서 서버에 빌리는 작업을 말합니다.

서버가 있어야 내가 업로드한 내용들을 저장하고, 공유할 수 있기 때문입니다.


[호스팅 구매 예시]

위와 같이 저는 사이트 찾는게 귀찮기 때문에... 같은 회사(닷홈)에서 예시를 보여드리겠습니다.

다시 한 번 말씀드리지만 본인이 원하는 서비스와 가격이 합당한 사이트에서 하길 바랍니다.


1.무제한 웹 호스팅 탭에서 무제한 웹호스팅 신청 클릭합니다. 

  타 사이트도 거의 비슷하게 되어 있기 때문에 예시를 보고 다른 사이트에서 진행해도 무리 없을 것으로 보입니다.



2. 호스팅 종류 확인 후 결정하여 신청하기 누릅니다.

   타 호스팅 사이트에서도 보통 종류가 나누어져 있을 겁니다.

   도메인 연결이라는 항목이 있을 건데, 이건 타 사이트에서 구매한 도메인도 가능합니다. 

   다만 같은 사이트에서 호스팅, 도메인 둘 다 진행하면 분명 특혜는 있을 겁니다.

   따라서 내가 이런거 잘 모른다 하면 한 군데 정해서 도메인, 호스팅을 같이 하시는 것도 나쁘지 않습니다.


3. 예시로 무료호스팅 신청하기 를 진행했습니다. 

   (무료 웹 호스팅은 닷홈에서 구매한 도메인이 있어야 합니다.)

4. 결제 정보를 작성해야 합니다. 

   (정보가 채워져 있는 부분도 있고 넣어야하는 부분도 있었는데 개인정보를 보호하기 위해 지웠습니다.)   


5. 테마선택하기 부분에서 워드프레스를 눌러줍니다.

  그러면 ↓아래 이미지처럼 테마 선택가능한 영역이 나옵니다.

  워드프레스 기본설치 눌러줍니다.


  요즘은 호스팅 사이트에서 워드프레스를 기본으로 설치해주는 곳이 많습니다.

  없을 경우에 대한 포스팅도 별도로 진행하도록 하겠습니다.



6. 약관 동의 읽어보고 동의 후 진행합니다.

   이때 자신의 웹 호스팅 정보 / 계정정보 를 잘 알고 있어야 합니다.

   나중에 로그인 시 사용하거나 커스텀을 할 경우에 FTP를 이용하기 위해서 필요할 수 있습니다.


7. 신청하기 클릭


신청 완료가 되면 내 도메인, 호스팅 등록이 잘 되었는지 확인하는 작업이 남았습니다.

본인의 도메인 주소를 인터넷 주소창에 넣고 접속하면 됩니다.

닷홈에서 무료로 실험 해 볼 경우에는 '계정아이디.dothome.co.kr'을 주소창에 넣은 뒤 접속 해보면 됩니다.


사이트가 연결되어 있으면 도메인, 호스팅 설정이 완료 된 것입니다.

또한 워드프레스 설치가 되었는지 확인 하려면 본인의 주소 뒤에 /wp-admin을 붙여주면 됩니다.

ex) www.okayoon.com/wp-admin

ex) okayoon.dothome.co.kr/wp-admin

로그인하는 화면이 아래와 같이 나오면 성공적으로 도메인, 호스팅 등록 + 워드프레스 설치 작업이 완료 되었습니다.

(로그인 페이지의 디자인은 버전에 따라 다를 수 있습니다)



다음에는 워드프레스 관리자 설정에 대해 알아보도록 하겠습니다.





목표!

홈페이지 제작하기 위한 툴로 선정한 워드프레스에 대해 알아보자. 



워드프레스 기초 홈페이지 제작(1)

워드프레스(wordpress) 란?



2003년에 만들어진 홈페이지를 제작, 관리하는 프로그램입니다.

웹 사이트를 만들고 관리하는 것 중, 전 세계의 1/4이 사용할 만큼 사랑 받고 있고

타 CMS(content management system) 툴과 압도적인 차이로 세계 1위라고 합니다.


CMS 툴이라고 하며 CMS는 Contents Management System의 약자입니다.

쉽게 설명하자면 개발자가 코드로 홈페이지를 제작하는 것이 아닌, 툴을 사용해서 홈페이지를 제작할 수 있는 시스템입니다.

티스토리 블로그도 CMS에 해당합니다.


사용하려는 툴의 장점을 알아보고 진행하도록 하겠습니다.

내가 사용하는 툴이 이렇구나 하고 간단히 슥~ 읽고 가면 되겠습니다.


1. 간단한 interface로 쉽게 홈페이지를 제작 할 수 있습니다.

- 어드민 페이지를 사용하기 쉽다는 뜻으로 생각하면 될 것 같습니다.


2. 반응형 웹을 쉽게 만들 수 있습니다.

- 반응형 웹은 pc, 태블릿pc, 모바일 등의 디스플레이에서 최적화된 홈페이지라는 뜻입니다.

  (냉장고 문에 붙어있는 디스플레이 일수도 있고, 네비게이션이 될 수도 있습니다.)

  

  여기서 한 번 짚고 넘어갔다가 나중에 다시 말씀 드리겠지만,

  워드프레스 = 반응형 웹 은 아닙니다.

  워드프레스에 있는 테마가 반응형 웹을 지원할 수 있다는 것으로 알고 가셔야 합니다.


3. 수 많은 테마와 플러그인 존재합니다.

- 내가 개발하지 않고 남이 개발한거 가져다가 사용할 수 있다는 뜻입니다.

  그것도 글로벌하게 만든 것을 사용할 수 있습니다.

  조합만 잘해도 홈페이지 만들 수 있다? 라고도 생각하면 좋을 것 같습니다.

  (슬라이드, 데이터 폼, 메뉴 바 등)


4. 저렴한 구축 비용입니다.

- 생각하기 나름입니다, 내가 제작하기 때문에 저렴한 구축 비용이라고 하는 건데...

  만들어진 테마 구매해서 제작한다고 해도, 어느정도 공부하지 않으면 불 가능 하기 때문입니다.   

  

5. 세계적으로 많이 쓰다보니까 사용자 포럼이 잘되어있습니다.

- 글로벌 서비스이다보니, 본인이 영어를 잘하면 잘 할 수록 도움이 많이 됩니다.

  그렇다고 국내 포럼이 없는 것이 아니니 잘 이용하면 도움이 많이 됩니다. 

- 도움 되는 사이트 링크 작성해 두겠습니다.

1.워드프레스 사이트(영문)

 2.워드프레스 사이트(국문)

 3.한국워드프레스 사용자 모임

  https://wordpress.org/

 https://ko.wordpress.org/

 https://kopress.kr/

한국 워드프레스 사용자 모임 같은 경우는 사용자 게시판에 질문하면 운영진께서 답변을 해주십니다. 도움이 많이 됩니다.


워드프레스로 제작되어 운영되고 있는 홈페이지 참고 사이트 두 곳 링크

블로터닷넷

 lg전자 블로그

 http://www.bloter.net/

 https://social.lge.co.kr/


참고사이트를 보면, 사이트는 같은 툴을 사용한다고 해도 어떻게 만들기 나름입니다.


다음에는 웹 벤치마킹하는 방법에 대해 알아보도록 하겠습니다.

12byte를 초과하면 작성이 더는 안되게 해달라는 요구사항의 작업을 하였다.

코드

$(function(){ 

  // byte 체크 할 타겟 (input, textarea) 
  var $target = $('#name'); 

  // 값이 들어올때는 input, 커서가 들어오고 나갈때는 focus, focusout 
  $target.on('input focus focusout', function(){ 
  	bytesValidationChk($(this),12); // 12자까지 
  }); 

  // 체크 함수 
  function bytesValidationChk(target, maxByte) { 
	  // byte 체크 할 때 사용하는 함수들 선언 
    var returnVal = ''; 
    var currentLength = 0; 
    var codeByte = 0; 

    // input의 value 
    var targetVal = target.val(); 

    // input.length만큼 반복
    for(var i = 0; i < targetVal.length; i++){ 
      // 한글, 영문 등의 byte만큼 codeByte를 증가 
      var oneChar = escape(targetVal.charAt(i)); 

      // 한글 = 2byte 나머지 = 1byte 
      if(oneChar.length > 4) {
        codeByte += 2;
      }else {
        codeByte++;
      } 

      // length 체크 
      // codeByte 값이 내가 지정한 maxByte보다 작을 때 = currentLength 값을 1씩 증가 
      if(codeByte <= maxByte) {
        currentLength = i + 1;
      } 

    } 
  
    // codyByte가 내가 지정한 maxByte보다 커지면 
    if(codeByte >= maxByte){ 
      // currentLength만큼 targetVal를 잘라줘서 returnVal에 담아줌 
      returnVal = targetVal.substr(0, currentLength); // 한글로 12byte면 currentLength가 6임 

      // maxByte만큼 자른 returnVal를 target(input)에 value로 넣어줌 
      target.val(returnVal)	; 
    } 
  } // bytesValidationChk

});

여기서 문제가 된건....
ie8에서 input 이벤트가 적용되지 않는 것이었다.

(focus와 상관 없이 자판을 쳤을때 체크해서 복+붙 시에도 체크가 가능해야 했다)


따라서 key 이벤트를 당연히.. 넣어줬어야 했는데, 이렇게 되면 ctrl+a(전체선택)이 적용되지 않는다.
큰 문제는 아니지만, 누군가는 당연히 복+붙을 할터이니.. 이슈로 돌아올게 분명하다.

+ firefox 버전 61.0.1(2018.07.11 기준으로 최신)에서는 한글에 key 이벤트 적용이 안된다.
과거부터 있던 이슈라는데, 한글이 완성형 글자라서 그러느니 뭐라느니, 그래서 이때는 input태그를 필수로 사용했다.★

그래서 처음 해본게.
value값을 새로 넣는게 아니라 target.attr('maxlength')값에 접근해서 cuttrneLength값을 넣어주는 방법도 했는데,
이 방법은 복+붙 시에 완전히 적용되지 않더라...
(byte가 maxByte가 되면 maxlength 추가, 아니면 제거 형식)

그래서 그냥 ie8은 key이벤트를 추가하여.. ctrl+a를 포기하기로 했다. (이 이하는 아몰랑)
마우스로 드래그하면 적용이 되니까....(흑흑)

수정된 코드이다.

$(function(){

  var $linkBtnInput = $('.domain-link-btn-wrap').find('.link-input');

  // 링크 이벤트를 기본으로 선언...
  var linkEvent = 'input focus focusout';

  // 브라우저 property를 사용해서 버전을 return받고
  var isIE = function(){
    var myNav = navigator.userAgent.toLowerCase();
    return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
  };
  
  // 비교하여 ie8이면 이벤트를 재 선언한다..
  if (isIE () == 8) linkEvent = 'input keyup focus focusout';

  // 아래는 위와 같다. 
  $linkBtnInput.on(linkEvent, function(){
  	bytesValidationChk($(this),12);
  });

  function bytesValidationChk(target,maxByte){
    var returnVal = '';
    var currentLength = 0;
    var codeByte = 0;
    var targetVal = target.val();
    
    for (var i = 0; i < targetVal.length; i++) {
      var oneChar = escape(targetVal.charAt(i));
      
      if(oneChar.length > 4) {
          codeByte += 2;
      }else{
          codeByte++;
      }

      if(codeByte <= maxByte){
          currentLength = i + 1;
      }
    }
    
    if(codeByte >= maxByte){
      returnVal = targetVal.substr(0,currentLength);
      target.val(returnVal);
    }
  }
  
});

더 좋은 방법을 알았으면 좋겠다 (헝헝 ㅠㅠ)

+ Recent posts