[DEV] 리액트 04 - Life Cycle

headerimg

경고

공부기록용임. 코드나 커리큘럼 방식 등 모든 지적 재산권은 노마드 코더에게 있으며, 무료로 볼 수 있으니 들어가서 여기서 공부할 것!! 갓 니콜라이 노마드 코더님 만세! https://academy.nomadcoders.co

Life Cycle

image

공식문서 무려 한글이다. 감동..ㅠ 꼼꼼히 읽어보자

공식문서
API

자주쓰는 컴포넌트 함수들

1. 마운트

constructor() // 초기화
render() // 랜더링
componentDidMount() //컴포넌트가 마운트 된 후 (랜더 후)
// DOM이 필요한 작업은 여기서

component가 실행될 때, 실행되는 녀석들이라고 편하게 생각하자.

2. 업데이트

shouldComponentUpdate()
//랜더가 필요하지 않은 state 변경을 하였다면 업데이트 할지 말지 (성능 최적화)
render()
componentDidUpdate() //업데이트 랜더링 된 후!

props, state가 변경될 때, 실행된다.

3. 마운트 해제

componentWillUnmount() //컴포는트가 없어질때 씀.

ngDestroy랑 비슷하다.

결과! image

componentWillUnmount는 나중에 시험해보자..ㅠ

[DEV] 리액트 03 - class & state

headerimg

경고

공부기록용임. 코드나 커리큘럼 방식 등 모든 지적 재산권은 노마드 코더에게 있으며, 무료로 볼 수 있으니 들어가서 여기서 공부할 것!! 갓 니콜라이 노마드 코더님 만세! https://academy.nomadcoders.co

Props

1. class & state state를 쓰기 위해선 이전에 쓰던 function component가 아닌 class component가 필요하다.

class App extends React.Component{
  // state는 object이고 여기 넣는 데이터는 변한다.
  state = {
    count: 0
  }
  // Ract는 자동적으로 class component의 render를 실행시킨다.
  render(){
    return <h1> count : {this.state.count}</h1>
    // 기본적으로 javascript class이니 this로 가져올 수 있다.
  }
}

기본적인 class component이다. class가 뭔지 모르겠다면 es06에 대한 강의를 봐야한다! 다음은 this.state.count를 증가 시킬 버튼과 함수를 만들어본다.

class App extends React.Component{
  state = {
    count: 0
  }
  add = () => {
    this.state.count += 1;
    // 이게 먹힐까?
  };
  minus = () => {
    this.state.count -= 1;
    // 이게 먹힐까?
  };
  render(){
    return (
      <div>
        <h1> The number is : {this.state.count}</h1>
        <button onClick={this.add}>add</button>
        <button onClick={this.minus}>minus</button>
      </div>
    )
  }
}

자 만들었다. 그럼 state를 변경하면 짠~ 되겠지! image

안된단다.. setState()를 사용하라고? 아 set get 말하는거군!
녀석 귀찮게 구는구나

state를 직접 변경하면 render function은 refresh 되지 않는다. 음.. OK state는 setState()로 바꿔야 render()가 DOM을 리프레쉬 하는구나. 거기다가 render() 함수는 똑똑해서 state가 변하는 부분만 바꿔준다.

image 세상 좋아졌네 신기하구먼..

angular ngModel이나 데이터 바인딩과 비슷하네! 이놈도 문제가 많아서 Mobx나 redux를 쓴다고 리액트 개발자가 짧게 알려준적이 있다.
이유는 차차 알아가겠지? 학습은 redux고 실 사용은 mobx를 쓴다는 팁도 받았다.

// 결론은?
class App extends React.Component{
  state = {
    count: 0
  }
  add = () => {
    // setState에서 current는 현재 상태를 받아온다.
    this.setState(current => ({count: current.count + 1 }))
  };
  // 이래도 되고~ 저래도되고 여튼 돌아간다.
  minus = () => {
    this.setState(function(current){
      return {count: current.count - 1}
    })
  };
  render(){
    return (
      <div>
        <h1> The number is : {this.state.count}</h1>
        <button onClick={this.add}>add</button>
        <button onClick={this.minus}>minus</button>
      </div>
    )
  }
}

[DEV] 리액트 02 - Props

headerimg

경고

공부기록용임. 코드나 커리큘럼 방식 등 모든 지적 재산권은 노마드 코더에게 있으며, 무료로 볼 수 있으니 들어가서 여기서 공부할 것!! 갓 니콜라이 노마드 코더님 만세! https://academy.nomadcoders.co

Props

1.기본 Props 전달

function App() {
  return (
    <div className="App">
      // Component의 시작은 대애문자
      <Movie title="IronMan"></Movie>
      // App Component는 Movie Component에 title이라는 Property에 IronMan이라는 value값을 주었다.
      <Movie title="Batman"></Movie>
      // 여러개도 가능
    </div>
  );
}

// 이렇게 Object로 온다.
function Movie(props) {
  return <h1>Movie Title is {props.title}</h1>;
}

// es6로 이렇게하는 것도 가능
function Movie({title}) {
  return <h1>Movie Title is {title}</h1>;
}

2. 어…Dynamic! 구려.. 맞다 반복을 직접하다니 역겹기 그지없다.
API호출된 리스트를 동적으로 뿌려보자.

const movies = [
  {
    name: 'Iron Man',
    image: 'https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2Fpre04.deviantart.net%2F1d43%2Fth%2Fpre%2Ff%2F2017%2F050%2F9%2F8%2Fspider_man__homecoming___iron_man_poster_by_bakikayaa-dazn0du.jpg&f=1&nofb=1',
  },
  ......
]
// 이렇게 생긴 놈을 API에서 받아왔다고 치고 ~

function App() {
  return (
    <div className="App">
      {movies.map((movie) => {
        return <Movie name={movie.name} image={movie.image} />;
      })}
    </div>
  );
}
// for.map을 이용해서 반복시키고 Movie Component를 리턴한다.

function Movie({ name, image }) {
  return (
    <div>
      <h1>Movie Title is {name}</h1>
      <img src={image}></img>
    </div>
  );
}
// 대애애충 이렇게 받으면 끝 ngFor랑 비슷하구먼! 쉽네

무슨 에러가 뜨긴하지만 잘된다~

headerimg

하.. 뭐래는거야.. 리스트에 모든 새끼들은 유니크한 키가 필요하다는군. 지가 하면될껄 에혀..

const movies = [
  {
    id: 1,
    name: 'Iron Man',
    image: 'https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2Fpre04.deviantart.net%2F1d43%2Fth%2Fpre%2Ff%2F2017%2F050%2F9%2F8%2Fspider_man__homecoming___iron_man_poster_by_bakikayaa-dazn0du.jpg&f=1&nofb=1',
  },
  ...
] // 이렇게 id를 만들어주고

function App() {
  return (
    <div className="App">
      {movies.map((movie) => {
        return <Movie key={movie.id} name={movie.name} image={movie.image} />;
        // key라는 prop에 id값을 넣어주면된다.
        // 이 key 값은 Movie Component에서 받아서 쓰지 않아도 된다. 내부적으로만 사용한단다..
      })}
    </div>
  );
}

멋지게 잘반복한다. 쉽네 쉬워

3. Props Type 근데 반복은 좋은데 만약에 Movie Component에 Prop을 잘못 보내거나 없는걸 보내면 어떻게하지?

npm i prop-types

설치!

import PropType from 'prop-types';

// 레이팅을 추가함.
function Movie({ name, image, rating }) {
  return (
    <div>
      <h1>Movie Title is {name}</h1>
      <img src={image} alt={name}></img>
      <p>{rating} / 5</p>
    </div>
  );
}

Movie.propTypes = {
  name: PropTypes.string.isRequired,
  image: PropTypes.string.isRequired,
  rating: PropTypes.number
}

function App() {
  return (
    <div className="App">
      {movies.map((movie) => {
        return <Movie 
          key={movie.id} 
          name={movie.name} 
          image={movie.image} 
          rating={movie.rating}/>;
      })}
    </div>
  );
}

Movie Component에 Props를 던져줄 때 마다, PropTypes가 체크해주고 없으면 디폴트 값까지 만들어서 던져준다. typescript에 있는 기능 처럼 매우 좋은 녀석인듯.

대문자 소문자가 매우 햇갈려서 초반에 어리버리 탈 수 있음.

[DEV] 리액트 01 - 가볍게 인스톨과 시작

headerimg

경고

공부기록용임. 코드나 커리큘럼 방식 등 모든 지적 재산권은 노마드 코더에게 있으며, 무료로 볼 수 있으니 들어가서 여기서 공부할 것!! 갓 니콜라이 노마드 코더님 만세! https://academy.nomadcoders.co

Why REACT?

많은 사람들이 한국은 다른 프레임워크 보단 REACT님이 최고시다. 라고 하는 소리를 듣는다. 나도 처음은 프론트 프레임워크를 angularJS로 시작해서 맞아 angular가 얼마나 좋은데! 라고 생각 했지만

사실 전 세계적으로 압도적 인기중임..

headerimg 맨위 진한 파란색이 리액트!

headerimg 71.7%가 사용해보고 다시 사용할 것이다. 12%가 흥미있다.
무려 83.7%가 만족하는 프레임 워크라는 것..

출처:stateofjs

Install

node 설치

npm

npm i -g npx

react-create-app 깃링크

Quick Start!

npx create-react-app my-app

cd my-app

npm start

[DEV] CSS OBJECT-FIT과 IE에서 사용하기

headerimg

  1. Object-fit은?
  2. Object-fit을 사용할 때, IE는 어떻게 할까?
  3. 예제
  4. 원리

Object-fit은?

CSS object-fit은 컨테이너에 맞게 <img>, <video> 등의 크기를 조정하는 방법을 지정한다. 음.. 그렇구나 근데 IE는 쓰지 못한다.

Object-fit을 사용할 때, IE는 어떻게 할까?

img

나의 최대의 적 IE에서는 이렇게 간편하고 좋은 css 속성을 쓰지 못한다.

CSS에서 이미지를 사이즈에 맞게 맞춰준다. 이해하기 쉽도록 간단한 예제를 만들었는데 눈으로 직접 보면 설명이 될 것이다.

예제

For IE는 object-fit에서 가장 많이 사용하는 cover와 같이 만들었다.

처음은 ‘none’으로 시작함. 요즘 하고있는 게임 카타나 제로 이미지를 이용함.

원리

편의상 jquery로 작성함.

<!-- for IE 버튼 부분 -->
<div class = "button-wrap last button-IE">
    <button class = "rad-button">for IE</button> 
</div>

<!-- 이미지가 들어있는 컨테이너 및 이미지 태그 -->
<div class="img-container">
  <img class="target" src="https://bit.ly/2GZUits">
</div>

function forIE(){
    var t = $('.target'), // 이미지 태그 
        s = 'url(' + t.attr('src') + ')', // 이미지 태그의 src를 가져옴.
        p = t.parent(), // 부모 컨테이너 '.img-container'
        d = $('<div class="backGround"></div>'); // div를 하나 만듦.

    t.hide(); //이미지는 숨기고.
    p.append(d); //부모div에 생성한 div를 붙임.

    d.css({
      'height'                : 300,
      'background-size'       : 'cover',
      'background-repeat'     : 'no-repeat',
      'background-position'   : 'center',
      'background-image'      : s ,
      'border'                : '1px solid red'
    });
}

위에 css 코드가 object-fit:cover 효과를 낸다.

[DEV] GULP BABEL을 이용한 기본 프로젝트

headerimg

GULP BABEL

// 외부 컴포넌츠 설정 
// 외부 프레임워크나 css가 필요하면 여기 등록하면 됨.
const COMPONENTS = [
  "src/components/jquery/jquery-3.4.1.min.js"
];
const COMPONENTS_CSS = [
  "src/components/flexboxgrid/flexboxgrid.min.css"
];

// 각 파일을 가져오고 내보내는 위치를 설정함.
// 말 그대로 ROUTES
const ROUTES = {
  pug: {
    watch: "src/**/*.pug",
    src: "src/*.pug",
    dest: "build"
  },
  img: {
    src: "src/img/*",
    dest: "build/img"
  },
  js : {
    watch : "src/js/**/*.js",
    src : "src/js/main.js",
    dest: "build/js"
  },
  scss: {
    watch: "src/scss/**/*.scss",
    src: "src/scss/style.scss",
    dest: "build/css"
  }
};
// 서버로 내보낼 때, 쓰기 위한 전역 변수.
var production = false;

// 컴포넌츠를 모두 가져와 bundle.css, js로 합쳐서 내보냄.
const components = () => {
  var JS_TASK, CSS_TASK;
  JS_TASK = gulp.src(COMPONENTS)
    .pipe(concat('bundle.js')) 
    .pipe(stripDebug()) // 콘솔 로그를 지움
    .pipe(uglify()) // min 파일이 아닌 경우에 어글리 파이를 해주기 위함
    .pipe(gulp.dest(ROUTES.js.dest));
  CSS_TASK = gulp.src(COMPONENTS_CSS)
    .pipe(concat('bundle.css')) 
    .pipe(miniCSS()) // 미니파이해줌.
    .pipe(gulp.dest(ROUTES.scss.dest));
  return merge(JS_TASK, CSS_TASK); // 두가지 테스크를 한 후 합쳐서 내보내준다.
}

// PUG 파일을 HTML로 컴파일
const pugBuild = () => {
  return gulp
    .src(ROUTES.pug.src)
    .pipe(g_pug())
    .pipe(gulp.dest(ROUTES.pug.dest));
};

// 이미지를 압축 최적화 해줌.
const imgBuild = () => {
  return gulp
    .src(ROUTES.img.src)
    .pipe(g_img())
    .pipe(gulp.dest(ROUTES.img.dest));
};

// ES06를 바닐라 JS로 변환 후 uglify 해준다.
const jsBuild = () => {
  return gulp
    .src(ROUTES.js.src)
    .pipe(bro({
      transform: [
        babelify.configure({ presets: ["@babel/preset-env"] }),
        [ 'uglifyify', { global: true } ]
      ]
    }))
    .pipe( gulpif(production, stripDebug()) ) // 만약 릴리즈 할 경우 콘솔로그를 모두 지워줌.
    .pipe( gulp.dest(ROUTES.js.dest) );
}

const webserver = () => {
  return gulp
    .src("build")
    .pipe(
      g_ws({ livereload: true, open: true }) // 로컬에서 개발 서버를 오픈 후 라이브 로드 해줌.
    );
};

// SCSS를 빌드한다.
const scssBuild = () => {
  return gulp
    .src(ROUTES.scss.src)
    .pipe(sass().on('error', sass.logError))
    .pipe(autoprefixer()) // 다양한 브라우저에 최적화함.
    .pipe(miniCSS()) // 미니파이
    .pipe(gulp.dest(ROUTES.scss.dest));
};

// 깃허브에 지정 브런치에 릴리즈 해준다.
const deploy = () =>{
  return gulp
    .src("build/**/*")
    .pipe(ghPages({
      brach: "release"
    }));
}

// 감시할 목록
const watch = () => {
  gulp.watch(ROUTES.pug.watch, pugBuild);
  gulp.watch(ROUTES.scss.watch, scssBuild);
  gulp.watch(ROUTES.js.watch, jsBuild);
  gulp.watch(ROUTES.img.src, imgBuild);
};

// 매번 빌드 할때마다, 지워줘야함
const clean = () => {
  return del(["build/", ".publish"]);
};

//만약 릴리즈 한다면, 전역변수를 true 하여 다른 방식으로 작동하도록함.
//TODO: 다른 깔끔한 방법을 찾아볼 것..ㅠ
const onProduct = (done) => {
  production = true;
  done();
}

// 테스크 모음
const live = gulp.parallel([webserver, watch]);
const prepare = gulp.series([clean, components, imgBuild]);
const assets = gulp.series([pugBuild, scssBuild, jsBuild]);

// 명령어 모음
export const build = gulp.series([prepare, assets])
export const dev = gulp.series([build, live]);
export const release = gulp.series([onProduct, build, deploy]);
  1. 다양하게 응용이 가능하도록 기본만 지켰다.
  2. 프로젝트를 깃에 업로드 해놓았다. 참고하세용. 깃으로 연결

[game] Witcher3 모드 추천

headerimg

Witcher3 필수 모드와 편의성 모드 추천


모든 모드는 NEXUS MODS에서 다운 받습니다.

NEXUSMODS <- 가입 필수!



1. 그래픽 모드


Photorealistic Reshade

img

현실적인 리쉐이드 모드. 제작자가 스카이림이나 폴아웃4에서 영감을 받고 만들었다고함. 원본과 비교하면 정말;;



HD Reworked Project

img

HD텍스쳐팩으로 걍 필수중 에 필수


High Quality Faces

img img

모든 NPC들을 어느정도 하이퀄리티로 업그레이드 해준다. 물론 3명의 메인 NPC 퀄리티가 매우 좋아져서 인기가 많은 모드 중 하나.



2. 전투 관련 모드


Ultra Gore 2 - A Dismemberment Mod

img

울트라 고어모드는 심심했던 전투를 활기차게 바꿔줄 것이다!! 조금 과하다고 생각 할 수 도 있지만,.. 최애 모드 중 하나.



3. 편의성 모드


Over 9000 - Weight limit mod

img

부족한 무게를 늘려준다. 물론 치트 개념이긴 하지만 겜하다보면 불편해서 무게 + 200 과금 패키지를 팔면 사고 싶을 정도이니 ;;


All Quest Objectives On Map

img

위쳐3를 하다보면 결국엔 모든 퀘스트를 깨는 것을 목표로 할 것이다. 이 모드가 있으면 너무나 편하게 100% 달성을 할 수 있다.


Fast Travel from Anywhere

img

언제 어디서든 빠른 이동을 가능하게 해준다. 여행하는 재미가 좀 떨어져서 비추하지만 2회차 부터는 필수!!


Quest Sorting

img

지들 맘대로 널부러져있던 퀘스트 목록을 정렬해준다.


No Witcher Sense Zoom FX plus Toggle and Range

img

집안에서 위쳐센스를 키면 바로 토쏠리는 그대를 위한 모드!! 위쳐센스를 일반 시야와 똑같이 해준다.

[DEV] ECMAScript6 - Spread Operator(전개 연산자)와 쩌는 사용법 4가지

headerimg 004 - 펼쳐버렷 연산자

Spread Operator!의 기본


전개 연산자 or 펼침 연산자 겁나 편해서! 가독성이 좋아서! 많이 쓰게 될 연산자이다.

전개 연산자(spread operator)는 표현식(expression)은 2개 이상의 인수arguments(함수 호출 용)나 2개 이상의 요소elements(배열 리터럴 용) 또는 2개 이상의 변수(비구조화 할당 용)가 예상되는 곳에 확장될 수 있도록 합니다.

아잇; 이게 뭐래는거여. 응 코드나 봐~

1.함수에 인자로 전달

//배열을 요소 하나씩 받아야하는 함수가 있다고 치자.
function printLog(x, y, z) {
    console.log(x,y,z);
}
const hopeArray = ["게임", "사서", "하고싶다."];


printLog.apply(null, hopeArray);
// 이런 방식으로 하거나
printLog(hopeArray[0], hopeArray[1], hopeArray[2]);
// 아니면 printLog 함수를 수정해야했다.

//ECMA06에서는 
printLog(...hopeArray);
//이렇게 간단하게 사용하면 된다.


//응용
let numbers = [2, 5, 6, 1, 0];
Math.min(...numbers);

...을 통해서 apply없이 함수를 호출할 수 있다!

Array에서 개쩌는 팁 5개


2.배열 붙이기

let beer = ['시원한 맥주', '마시러'];
let offWork = ['퇴근하고', ...beer, '가고싶다.'];
let merge = [...beer, ...offWork]; //이런 방법도 가능

// 뒤나 앞에 붙이고 싶다면?
arr1.push(...arr2);
arr1.unshift(...arr2);

겁나 간단하다. 그냥 ...으로 배열을 껍데기를 깐다고 생각하면 쉽다.



3.배열 복사하기

let arr1 = [1,2,3];
let arr2 = [...arr1];
let arr3 = arr1.slice(0);

arr1.unshift("1번");
arr2.unshift("2번");
arr3.unshift("3번");

// "1 " ["1번", 1, 2, 3]
// "2 " ["2번", 1, 2, 3]
// "3 " ["3번", 1, 2, 3]

참고해야하는 것은 배열 속 객체는 얕은 복사를 한것이다. 객체의 깊은 복사는 스니핏이 따로 있다.



4.NodeList를 배열로 변환

let nodeList = document.querySelectorAll("li");
// "[object NodeList]"

// 변환할 변수에 대입.
let convertedSpread = [...nodeList];  
// "[object Array]"

//함수에 인자로 넣어줄 때.
const testFunction = function(...list) {
};
// "[object Array]"

//from()을 이용한 노드리스트를 배열로 변경.
let convertedFrom = Array.from(nodeList);
// "[object Array]"

node list를 추출하였을 때, 배열로 바꿔야 할 때가 은근 자주있다. 물론 from()을 통해 하는 방법도 있지만 보기도 편하고 함수에 직접 때려 박을땐, 이 방법이 가장 깔끔하다.

[DEV] Jekyll(지킬), Gitpages(깃페이지)에 커스텀 도메인 적용

headerimg 도메인 구매부터 gitpages에 등록하고 jekyll에 적용까지!

준비물

Github에 등록된 Gitpages!
ex : http://.github.io

일단 도메인을 구해보자!


Godaddy

싸다 최소 1099원으로 .com 도메인을 구매할 수 있다.


whois

유명함. 안써봐서 모른다.


gabia

지금 사용중인 업체, error404.co.kr 이 가장 싸서 여기서 구매했다.


freenom

무료이다. 단점으로는 홈페이지 자체가 무진장 느리고 여기서주는 몇몇 TDL은 구글에서 검색제한이 걸려있기도 하다.
나는 여기서 blow.gqbung.ga 라는 미친 짧은 도메인을 무료로 가지고있는데,
.gq는 특히 구글 서치 콘솔에서 sitemap이 1달넘게 리젝당한 경험이 있다.

그래 뭐든 샀다 어떻게 적용하지?

일단은 깃의 Settings에 가자.

image

아래로 쭉~ 내려가다보면 Github pages 라는 항목이 나온다.

image

여기서 custom domain에 자신의 도메인을 넣어주고 세이브!

다음은 도메인을 구매한곳으로

나는 일단 가비아에서 샀으니 가비아에서 진행한다. 다른 곳도 이런 방식이니 그냥 따라하면 된다.

image
image
image
image

A레코드에
192.30.252.153
192.30.252.154
이렇게 치면된다.

[DEV] ECMAScript6 - 새로운 Function

headerimg 003 - ECMAScript6를 짧고 핵심내용만 빠르게

이번은 함수!


이전에 쓰던 함수 선언들은?

//함수 선언식
function add(x, y){
  var sum = x+y;
  return sum;
}

//함수 표현식
var add = function(x, y){
  var sum = x+y;
  return sum;
}
  1. 보통은 이 두가지를 사용한다.
  2. 자가 호출 함수라는 것도 있다.
  3. 자세한 사용법은 여기에 가보자


ECMA06에서의 함수 선언 방식

var add = (x, y) => {
  var sum = x+y;  
  console.log(sum);
}
add(20, 1); // 21


//더 간단한 방식
const hi = x => "Hello " + x;
console.log( hi('World!') ); //  Hello World!
  1. 보면 알겠지만 이젠 더이상 function, return을 안써도 된다.
  2. 괄호와 중괄호도 생략할 수 있다. 그냥 => 끝.
  3. 매개변수가 없으면 ( ) 괄호는 써줘야한다.


그래서 어디다가 써먹어? 그냥 다 =>로만 쓸까? 정답은 NO다.

함수가 뭐하는 함수인지 모를 정도로 짧게 쓸 수 도 있으니 읽기 힘든 코드가 될 수 있다. 거기다가 요녀석이 => 좀 보기 힘든 구석도 있다. 그래서 선언을 function으로 하는 추세도 있다.

forEachmap같은 함수 내부에서 function 키워드 대신에 쓰는 것은 실제로 많이 권장하고 있다.

var arr = [2, 3, 7, 8];

//옛날 방식
arr.forEach(function(el) {
  console.log(el*2);
});

//ECMA06
arr.forEach(el => {
  console.log(el*2);
});

//평범한 함수 선언은 이런식으로 하는 것이 협업에 도움된다고 한다.(airbnb)
const short = function longUniqueMoreDescriptiveLexicalFoo() {
  // ...
};

그냥 function 대신에 => 에로우를 쓰면된다. 매개변수는 먼저쓰고 없으면 ( )써준다. 끗.

Pagination


© 2018. All rights reserved.