ReactJS Study #4

#4 React 기초 2

추천

Exploring ES6 번역 프로젝트입니다
ECMAScript2015를 학습하는 스터디입니다

forEach

var arr = [1, 2, 3, 4, 5];
for(var i=0; i<arr.length; i++){
 console.log(arr[i]); // 1 2 3 4 5
}
arr.forEach(function(v,i){
 console.log(arr[i]); // 1 2 3 4 5
 console.log(v); // 1 2 3 4 5
});
var newArr = arr.forEach( function(v,i){ return v; } );
newArr; 
// undefined (forEach는 return을 무시한다. 반환하는게 없다.)

// jquery
$.each([ 52, 97 ], function( index, value ) {
  alert( index + ": " + value ); // 0:52 1:97
});

map

var arr = [1, 2, 3, 4, 5];
var newArr = [];
for(var i=0; i<arr.length; i++){
 newArr[i] = arr[i];
}
newArr; // (5) [1, 2, 3, 4, 5]
var newArr = arr.map( function(v,i) { return v; });
newArr; // (5) [1, 2, 3, 4, 5]

reduce

var arr = [1, 2, 3, 4, 5];
var sum = 0;
arr.forEach( v => { sum += v; } );
console.log(sum); // 15
arr.reduce( (p, c) => p + c); // 15
// p:1 c:2 r:3, p:3 c:3 r:6, p:6 c:4 r:10, p:10 c:5 r:15
arr.reduce( (p, c) => p + c, 0); // 15
// p:0 c:1 r:1, p:1 c:2 r:3
arr.reduce( (p, c) => { return p + c; }, 'array' );
// "array12345"
arr.reduce( (p, c) => { p.c = c; return p; }, {} );
// {c: 5}
arr.reduce( (p, c) => { p[c] = c; return p; }, {} );
// {1: 1, 2: 2, 3: 3, 4: 4, 5: 5}
arr.reduce( (p, c) => { p.push(c); return p; }, [] );
// (5) [1, 2, 3, 4, 5]

// initialValue 미지정시 첫번째 요소가 previousValue가 되고 두번째 요소부터 순회
// initialValue 지정시 initialValue가 previousValue가 되고 첫번째 요소부터 순회

forEach / map / reduce

-arr.forEach((v, i) => {})
-arr.map((v, i) => {})
-arr.reduce((p, c, i) => {})

-arr.forEach(callback[, thisArg])
-arr.map(callback[, thisArg])
-arr.reduce(callback[, initialValue])
-thisArg 선택 사항. callback을 실행할 때 this로서 사용하는 값.
call또는 apply를 함수 안에서 해줌 or bind this
-initialValue 선택사항. callback의 첫 호출에 첫 번째 인수로 사용하는 값.

-forEach callback: currentValue, index, originalArray
-map callback: currentValue, index, originalArray
-reduce callback: previousValue, currentValue, currentIndex, originalArray
originalArray는 거의 쓸모없음

Array.prototype

var obj = {0:10, 1:20, 2:40, length:3};
Array.prototype.pop.call(obj);
obj; // {0: 10, 1: 20, length: 2}

var arr = [1, 2, 3, 4, 5];
var arr2 = arr.map(function(v){ return v > 3; });
// [false, false, false, true, true]
var arr3 = arr.filter(function(v){ return v > 3; });
// (2) [4, 5]

-console.dir(Array.prototype); // 배열 메소드를 알기 위해
-Array.prototype.filter() 메소드는 제공된 함수로 구현된 테스트를 통과하는 모든 요소가 있는 새로운 배열을 만듭니다.
-Array.prototype.every() 메소드는 배열의 모든 요소가 제공한 함수로 구현된 테스트를 통과하는지를 테스트합니다.
-Array.prototype.some() 메소드는 배열 내 일부 요소가 제공된 함수에 의해 구현된 테스트를 통과하는지를 테스트합니다.

MAP

{people.map((v, i) =>
  <Child
    key = {i}
    name = {v.name}
    phone = {v.phone}
    show = {v.show}
    handleClick={() => this.handleClick(i)}
  />
)}
// 충돌
{people.map((v, i) => <Child .. />)}
{people2.map((v, i) => <Child .. />)}
<Child key = {0} />
<Child key = {5} />
<Child key = {0} />
<Child key = {5} />

const people = this.state.people.map((v,i) => (
<Child
    key         = {`person#${i}`}
    handleClick = {() => this.handleClick(i)}
    { ...v }
  />
));
// { ...v } 데이터를 통틀어 다 넘긴다
// proposal 단계 (객체 펼치기)

자바스크립트를 엔진에서 돌릴 때 컴포넌트를 구분하기 위헤 key값이 필요하다.
APP 전체를 통틀어서 UNIQUE한 값이 좋다.
동일한 위치에 같은 컴포넌트를 호출할 때 key값은 충돌한다.

컴포넌트 명세

-render: 필수요소
-ES5 : getInitialState, getDefaultProps()
-constructor 내에서 this.state = {}으로 직접 설정
-defaultProps는 class 정의를 마친 다음에 별도로 설정 가능
-static defaultProps = {}으로 직접 설정 constructor보다 위에 위치시킬 것을 추천.
(babel-preset-stage-2 : Class properties transform 이하 설치 필요)
-defaultProps는 서버에서 값을 안 넘겨줄 때 or 데이터를 받을 때 유용
-propTypes는 타입체크, 추가적으로 패키지 설치가 필요하다
-defaultProps & propTypes 써도 되고 안써도 됨
-Child.prototype.render == c(__proto__).render
-Javascript를 Java처럼 만든게 Typescript
-타입체크는 경고 정도 보여준다.
-propTypes는 어라전까지 React안에 내장되어 있었지만 현재는 분리되어 Library 설치해야함
-Flow는 타입체크, 자바스크립트에서 사용 가능, 리액트랑 궁합이 좋다.
-propTypes.arrayOf는 배열의 요소가 숫자여야만 한다
-isRequired 필수요소 확인

The Component Lifecycle

component-life-cycle

-Component Instantiated
최초의 초기 단계, 컴포넌트가(Initial) 최초 불려질때
-componentWillMount() 시작하기 전에 실행하는 메소드
-shouldComponentUpdate(nextProps, nextState)
의문 할꺼니 말꺼니 묻는 메소드, 렌더링을 할지 말지를 판단하는 메소드
default true
메소드안에 여러 조건문을 걸어서 렌더링 호출 횟수 down, 성능도 up, 체감속도 up
성능을 끌어올리기 좋다
-componentWillReceiveProps(nextProps)
props는 내 의지로 바뀌는게 아니라서 상태 감지를 위한 메소드
-자바스크립트 최소 처리시간 10ms
setTimeout(call, 0) 10ms 후에 실행(브라우저 환경)
Timer 00:00:00:000 (매번 렌더링) 성능과 연관되어 시분초까지만
-componentDidUpdate(prevProps, prevState)
기존: willReceiveProps, shouldUpdate, willUpdate
여기서의 this.props는 기존의 nextProps와 같다
여기서의 this.state는 기존의 nextState와 같다
여기서의 prevProps는 기존의 this.props와 같다
여기서의 prevState는 기존의 this.state와 같다
-componentWillUnmount()
해당 메소드가 실행한 다음 묻지도 않고 곧장 삭제
-render하는 시점에 한번에

Truthy vs Falsy Data

if(!0) { console.log(true); } // true
var a = 10;
if(!a) { console.log(true); }
else { console.log(false); } // false

-Falsy Data – 0, ”, null, undefined, false, NAN
-0 값은 조건에서 제공될 때는 false
-!! boolean으로 바꿔줌 !!0, !!null, !!1(true), !![](true), !!{}(true)

Event Handling

document.addEventListener('click', function(e) { console.dir(e); });

var btn = document.createElement("button");
var text = document.createTextNode('click');
btn.appendChild(text);
btn.setAttribute('id','target');
document.body.appendChild(btn);
btn.addEventListener('click', function(e) { console.dir(e); });

$( "#target" ).click(function() {});
$( "#target" ).on('click', function() {});
// on or off 핸들러를 여러개 등록할 수 있어서 더 좋다.

SyntheticEvent
-Jquery도 다른 브라우저에서 동일하게 동작하도록 맵핑되어 있다.
-Evnet는 무거운 객체
-Evnet가 많으면 많을 수록 브라우저가 가지고 있어야 하는 데이터가 많다.
-event.persist()
-console.dir(e);
이벤트가 발생한 시점에만 보여주고 잊는다.
함수안에서만 볼 수 있고 그때만 값을 들고 있다.
[[Target]]: SyntheticMouseEvent
currentTarget: (…) invoke property getter
-console.dir(e.nativeEvent); // 값을 들고 있는다
currentTarget: null

Stateless Component

import React from 'react';

class Comp extends React.Component {
  render(){
    const {
      prop1,
      prop2
    } = this.props;

    reuturn(
      <div>
        {prop1} {prop2}
      </div>
    )
  }
}

const Comp = ({prop1,prop2}) => <div>{prop1} {prop2}</div>

const Comp = ({
  prop1,
  prop2
}) => (
  <div>
    {prop1} {prop2}
  </div>
);

export default Comp;

Components and Props

TodoApp

-기능설계
할일 추가 삭제 / doubleClick : 수정모드 / 수정Enter : 저장 / 수정(다른데를 클릭하면) : Cancel / Toggle (완료/미완성) / 전체토글 / 필터 / 완료 삭제
-Reference
http://todomvc.com/

5 Components

-main.js (realDom)
-App – Header / TodoList / Footer
-TodoList – Todo / Todo / Todo

https://github.com/react-study/reactStudy/tree/master/04_ReactBasic2

ReactJS Study #3

#3 React 기초 1

동영상

JQUERY

DOM을 변경할 때마다 메모리에 부담을 주고 비용이 발생한다
제이쿼리의 경우 매번 해당 노드를 찾고 함수를 실행하기 때문에 비효율적이다.
$(“.elem”) // $는 실제 함수를 호출한다
$(“.elem”).on(“click”, onClickHandler);
$(“.elem”).off(“click”, onClickHandler);
보완작업으로 var $elem = $(‘.elem’); 변수를 이용하지만 실시간 업데이트가 어렵다.
Ref. The difference between Virtual DOM and DOM

REFLOW & REPAINT

생성된 DOM 노드의 레이아웃 수치(너비, 높이, 위치 등) 변경 시 영향 받은 모든 노드의(자신, 자식, 부모, 조상(결국 모든 노드) ) 수치를 다시 계산하여(Recalculate), 렌더 트리를 재 생성 하는 과정.
또한, Reflow 과정이 끝난 후 재 생성된 렌더 트리를 다시 그리게 되는데 이 과정을 Repaint 라 한다.
Ref. Reflow 원인과 마크업 최적화 Tip

REACT

component -> Virtual Dom Real Dom
props or state 둘중 하나가 변경되면 컴포넌트를 다시 그린다.
virtual dom은 매번 새로 그리고 real dom과 비교해서 변경되는 부분만 적용을 한다.
빠름 : 레이아웃이 어느정도 고정된 형태에서 데이터가 변경될 때 (update)
느림 : 계속 새로운 데이터가 추가될 때 예를 들어 무한스크롤링 (create)

Without Install

// http://jsbin.com
<div id="root"></div>
<script src="./react.js"></script>
<script src="./react-dom.js"></script>
<script src="./browser.min.js"></script>
<script type="text/babel">
 ReactDOM.render(
 (<h1>Hello, World!</h1>),
 document.getElementById('root')
 );
</script>

react.js – 핵심기술
react-dom.js / react-native.js (역할분리)
The ReactDOM module exposes DOM-specific methods, while React has the core tools intended to be shared by React on different platforms (e.g. React Native).

With Webpack & Babel

// package.json
"devDependencies": {
  "babel-core","babel-loader","babel-preset-env","babel-preset-react","babel-preset-stage-1","react","react-dom","webpack","webpack-dev-server","webpack-hot-middleware","react-hot-loader": "next"
}
// react-hot-loader  자동으로 갱신

// webpack.config.js
const HOST = 'localhost';
const PORT = 8080; // localhost:8080
module.exports = {
  entry: [
    `webpack-dev-server/client?http://${HOST}:${PORT}`,
    './main.js'
  ] // 가상 메모리공간 서버
};

Original Type (ES5)

ES5로 작업 가능하지만 비효율적이고 JSX를 사용하려면 Babel를 사용해야 하니 Origianl Type은 비추천

ReactDOM.render

//----- main.js -----
import React from 'react';
import ReactDOM from 'react-dom';
import Parent from './Parent'
ReactDOM.render(
 (<Parent />),
 document.getElementById('root')
);

RealDom에 그리는건 ReactDom이 맡는다.
ReactDOM.render RealDom에 실제로 그려줌
ReactDOM.render(VirtualDOM, targetElement)

JSX 문법

{/* 각 property들은 expand 형태로 작성.*/}
<input
  id="Input"
  type="text"
  disabled={this.props.isFocused ? true : false}
  onClick={this.handleClickInput}
/>
{/* 하위요소가 불필요한 경우 단일태그로 처리할 수 있음. */}
{/* 이벤트 핸들러 등록은 위와같이. */}

-JSX 문법은 XML과 비슷, HTML이 아님
-JSX는 JS 안에!!
JSX Render안에 Return 뒤 (VirtualDom이 그릴꺼)
render() { return ( HERE ); }
-camelCase 로 표기
-최상단에는 반드시 하나의 엘리먼트만 존재해야 한다. 즉, 여러 형제요소들은 반드시 부모요소로 감싸야 한다
-꼭 닫는 태그 사용
<br /> <input /> <div /> <span />
-Component를 태그처럼 사용할 수 있다
-Component는 첫글자 대문자로 표기 (html 태그랑 구분하기 위해)
eg. class header extends React.Component { .. }
-주석 {/* comment */} comment element 하나의 노드
비어있는 값으로 인식, 최상단에 위치하면 에러남
-{ } 는 꼭 값이어야 한다.
eg. {10}, {‘abc’}, {{a:1}}, {[1,2,3]}, {func()}, {abc.abcd()}, {a===b&c||d}
(for문 같은건 안됨 {for(x=1;x<10;x++){})
-띄어쓰기가 되지 않음 그래서 다음과 같이 사용
<span>HI</span>{‘ ‘}<span>World</span>
-jQuery경우 두가지 방법을 쓰지만 JSX는 전자의 방법만 씀
$( this ).css({backgroundColor: “red”});
$( this ).css(“background-color”, “red”);
-class는 className으로 <div className=”a”></div>
<div class=”a”></div> class A extends {} (JSX는 클래스로 인식)
-‘for’는 ‘htmlFor’로 <label htmlFor=”a”>Label</label>
<label for=”a”>Label</label> (JSX는 for문으로 인식)
-style은 객체로 써줘야함
style={{ color: ‘#000′,fontSize: ’16px’,marginTop: 20, lineHeight: 1.3 }}
-코딩 컨벤션 두줄이상은 내려준다
Ref. JSX In Depth

props & states

//----- Parent.js -----
class Parent extends React.Component {
  render() {
    return (
      <div>
        <Child name="gomugom" gender="male" />
        <Child name="iu" gender="female" />
      </div>
    )
  }
}
// <Child /> 각각의 state
// <Child /> === new Child() 클래스의 인스턴스화
// <App /> //Instance of the component App
// name, gender는 JSX attributes
//----- Child.js -----
class Child extends React.Component {
  /* static property
  static defaultProps = {
    name: '이름없음',
    gender: '성별없음'
  };
  */
  render() {
    const { name, gender } = this.props;
    return (
      <div>
        <h2>{name}</h2>
        <strong>{gender}</strong>
      </div>
    )
  }
}
Child.defaultProps = {
  name: '이름없음',
  gender: '성별없음'
}; // static property

props (properties 속성)
내 의지와 상관없이 / 저절로 생겨나는것 / 부모님의 영향을 크게 받음 / 부모님이 바꾸면 영향을 받는다 / 부모님 이것좀 바꿔주시면 안되요? / 태어난 지역 같은거 결론. 내 의지로 바꿀수 없음
states (상태)
내 의지로 바꿀 수 있음 / 부모님과 하등 상관이 없음 / 내가 만든 데이터 / 내꺼 / 내가 바꾸지뭐

main.js / Parent.js / Childe.js 각각 독립됨
실세 자바스크립트 클래스 상속은 extends 이므로 React.Component로 부터 상속받음
Parent.js에서 Child.js 인스턴스화, JSX 호출로 Child.js가 Parent.js의 자식이 됨
실제 상속 관계는 아니지만 데이터 관점에서 부모와 자식 관계
<div><span></div>와 비슷함 <Parent><Child /></Parent>

부모/자식 component간의 통신

//----- Parent.js -----
<Child
 name={ people[0].name }
 phone={ people[0].phone }
 show={ people[0].show }
 handleClick={this.handleClick.bind(this, 0)}
 />

{people.map((v,i) =>
 <Child
 key={i}
 name={v.name}
 phone={v.phone}
 show={v.show}
 handleClick={() => this.handleClick(i)}
 />
 )}

-React의 원칙 : 위에서 아래로 흐른다, 위에서 가져가게 한다.
-<Parent>
<Child key={val} /> state(o)
this.props = {key:val}
</Parent>
위에서 아래로 props(o) 아래에서 위로 (x)
-아래에서 위로 통신하는 방법은
Parent가 Child에게 위임한 메소드를 호출하는 방법
Parent가 내려줘야하고 허락해줘야만 Child가 실행할 수 있다.
-예제코드에서 const { name, phone, show, handleClick } = this.props;
부모님이 내려주신 handleClick

state
-render는 데이터가 바뀔떄마다 실행 (props or state)
-constructor(props) { super(props); }
super() – 클래스 상속 부모의 초기화 기능 추가
-this.state = { .. };
최초 선언시에만 쓴다, constructor 안에서만 써라
-this.state.people = newPeople;
render호출이 되지 않는다. react가 원하는 감시제가 되지 않는다. 가능하면 사용하지 마세요.
-this.setState({ .. });
state를 바꾸고 나서 (merge를 하고나서) render 메소드를 호출한다.
-state는 객체
this.state={a:1, b:2}; this.setState({b:3}); this.state={a:1, b:3};
setState는 새로 덮어쓰는게 아니고 관련 부분만 바꾼다.
-construct안에 setState를 쓰면 두번 render 실행

ref

//----- Parent.js -----
class Parent extends React.Component {
  handleClick() {
    this._input.focus();
  }
  render() {
    return (
      <div>
        <input
          type="text"
          ref={ ref => { this._input = ref }}
        />
        <button
          onClick={()=> this.handleClick()}
        >
          클릭!
        </button>
      </div>
    )
  }
}

-reference
-react가 dom 스크립트 대부분을 제어
except document.getElementById & document.querySelector
-state나 props로는 수행할 수 없는 DOM 제어 등을 위한 추가수단
-가급적 ‘데이터흐름’과 무관한 경우에만 활용할 것 (react랑 별개인것만)
-Dom 선택시 비용 발생
-this._input  <input />

DEBUG

-Chrome 확장도구 React Developer Tools
-먼저 Console 확인 (browser)
-다음 Terminal 확인 (bundling)
-최종 React 확인 (bundling)

https://github.com/react-study/reactStudy/tree/master/03_ReactBasic1
FiraCode ===

ReactJS Study #2

#2 ReactJS를 작성할 때에 알아두면 좋은 ES6 문법들
최신 브라우저 약 98% 정도가 ES6를 지원 (특히 크롬과 사파리)

1. block scope

자바스크립트에서는 함수 유효 범위를 지원한다.
ES6에 block scope {} 추가
즉시실행함수와 유사 (function(){})() (코드를 지역 유효범위로 감싸다)
예) if, for, while, switch

2. block scoped variables

블록 변수 – let & const (상수변수)
TDZ (temporal dead zone, 임시사각지대)

let a = 10; let a = 20; // SyntaxError
var a = 10; let a = 20; // SyntaxError
let a = 10; var a = 20; // SyntaxError
const a = 10; a = 20; // TypeError
const a; // SyntaxError (선언 동시에 할당 해야함)
const a = {x:1, y:2}; a = [1, 2]; // TypeError
const a = {x:1, y:2}; a.x = 10;
// a는 객체를 가르키는 참조값, a.x는 참조하는 객체의 프로퍼티

let a; console.log(a); // undefined
console.log(a); let a; // ReferenceError
{ let a = 1; { console.log(a); let a = 2; } } // ReferenceError

var a = 10; console.log(window.a); // 10
delete a; delete window.a; // false
// 전역 변수는 전역 객체의 프로퍼티들
window.a = 10; delete window.a; // true
let a = 10; console.log(window.a); // SyntaxError

-블록스코프는 실행컨텍스트가 생기지 않는다, this를 바인딩 하는 과정이 없다.
-함수스코프 내에서 this는 바인딩 되지만 arrow function은 this를 바인딩하지 않는다.
-ES6에서는 함수 선언문 사용을 지양
-함수 선언문은 ‘use strict’ 사용하면 블록 스코프 영향을 받는다.
-함수 선언문은 선언 동시에 정의함으로 호이스팅이 되며 TDZ가 적용되지 않음

Understanding delete

var GLOBAL_OBJECT = this;

/* `foo` is a property of a Global object.
It is created via variable declaration and so has DontDelete attribute.
This is why it can not be deleted. */

var foo = 1;
delete foo; // false
typeof foo; // "number"

/* `bar` is a property of a Global object.
It is created via function declaration and so has DontDelete attribute.
This is why it can not be deleted either. */

function bar(){}
delete bar; // false
typeof bar; // "function"

/* `baz` is also a property of a Global object.
However, it is created via property assignment and so has no DontDelete attribute.
This is why it can be deleted. */

GLOBAL_OBJECT.baz = 'blah';
delete GLOBAL_OBJECT.baz; // true
typeof GLOBAL_OBJECT.baz; // "undefined"

Object.freeze

const obj = { prop1:1, prop2:[2, 3, 4], prop3:{a:1, b:2} };
Object.freeze(obj);
obj.prop1 = 3; obj.prop2.push(5); obj.prop3.b = 3;
console.log(obj);
// obj = { prop1:1, prop2:[2, 3, 4, 5], prop3:{a:1, b:3} }
// obj 객체를 그 내부까지 완전히 얼리려면, 재귀 호출로 obj 내의 모든 객체를 각각 얼려야 함, deep freezing 함수를 구현

jQuery.extend

jQuery.extend( [deep ], target, object1 [, objectN ] )
// deep : boolean
// If true, the merge becomes recursive (aka. deep copy). Passing false for this argument is not supported.
// false : shallow copy 객체인 경우 해당 객체를 복사하지 않고 참조한다
// 보통 extend 함수를 구현하는 경우 대상이 객체일 때는 깊은 복사를 하는것이 일반적
var object = $.extend({}, object1, object2);
var a = $.extend( {width:100, height:100, delay:300}, {width:300, delay:500} );
console.log(a); // Object {width:300, height:100, delay:500}

3. arrow function

function a() { return x; }
const a = () => x;

var sum = function(a, b) { return a + b; }
const sum = (a, b) => { return a + b; }
const sum = (a, b) => a + b;

var getDate = function(){ return new Date(); }
const getDate2 = () => new Date();
console.dir(getDate); // prototype 속성이 있음
console.dir(getDate2); // prototype 속성이 없음

const obj = {
  grades: [80, 90, 100],
  getTotal: function() {
    this.total = 0;
    this.grades.forEach(v => {
      this.total += v;
    });
  }
};
obj.getTotal();
console.log(obj.total);  // 270

-우측이 여러줄로 이루어져있다면 { }로 묶을 수 있으며, 이 경우엔 명시적으로 return을 기술하지 않으면 undefined가 반환된다.
-arrow function은 prototype 속성이 없다. 생성자 함수로 사용할 수 없다.
-생성자 함수를 사용하려면 클래스 문법을 사용하라.
-화살표 함수는 자신만의 this를 생성하지 않습니다. this는 감싸고 있는 컨텍스트로 부터 원래의 의미를 갖습니다.
-화살표 함수에서는 this가 바인딩되지 않았기 때문에, call() 또는 apply() 메서드는 인자만 전달 할 수 있습니다. this는 무시됩니다.
-화살표 함수는 this가 상위 객체에 this를 받기 때문에 내부 함수로 사용하기 좋고 기존처럼 변수 selft나 that 변수에 this를 할당하여 사용하지 않아도됨
-콜백 함수로 사용하기 좋다.

4. rest parameter & 5. spread operator

function f(...rest){
console.log(arguments); // 유사배열
console.log(rest); // 배열
}
f(1, 2, true, null, undefined, 10);
[1, 2, true, null, undefined, 10, callee: (...), Symbol(Symbol.iterator): function] //arguments
(6) [1, 2, true, null, undefined, 10] // rest
// 기존에 흔히 사용하던 Array.prototype.slice.call(arguments) 이런거 안써도됨

function f(..rest, x){ } // SyntaxError
function f(x, ..rest, y){ } // SyntaxError

const str = 'abcdef';
const arr = str.split(''); // ["a", "b", "c", "d", "e", "f"]
const arr2 = [...str]; // ["a", "b", "c", "d", "e", "f"]
// 기존에 forEach문으로 값을 복사하던걸 편리하게 사용

const originalArray = [1, 2];
const copiedArray = [...originalArray];
originalArray.push(3);
console.log(originalArray); // [1, 2, 3]
console.log(copiedArray); // [1, 2]

6. default parameter

var n = null;
console.log(typeof n); // Object
console.log(n === null); // true

function f(value){
  if(!value) { console.log('empty'); }
}
// value가 false인 경우 "", null, undefined, 0, NaN, 그 외는 true
// value == undefined null or undefined인 경우 true
// value === undefined undefined인 경우 true

function f(x, y, z){
  x = x ? x : 10;
  if(!y) y = 20;
  z = z!=='undefined' ? z : 30;
  console.log(x, y, z);
}
f(0, '', null); // 10 20 null
function f(x = 10, y = 20, z = 30){
  console.log(x, y, z);
}
f(0, '', null); // 0 "" null
function f(x = 10, y = x){
  console.log(x, y);
}
f(); // 10 10
function f(x = y, y = 10){
  console.log(x, y);
}
f(); // ReferenceError

파라미터에 값을 할당하지 않거나 빈 값인 상태로 함수를 호출할 경우, 해당 파라미터를 지정한 기본값으로 인식하도록 해줌. 각 파라미터는 내부에서 let과 동일하게 동작하며, 따라서 TDZ가 존재한다.

7. enhanced object literal

// computed property key
const obj = {};
obj['a b c'] = 10; // 10
const obj = { ['a b c']:10 }; // ES6
// property Shorthand
// 프로퍼티의 키와 값에 할당한 변수명이 동일한 경우, 키를 생략할 수 있다.
const a = 10, b = 20;
const obj = { a: a, b: b };
const obj = { a , b };

const set= (a, b, c) => { a, b, c }; // undefined
const set = (a, b, c) => ({ a, b, c }); // { a:1, b:2, c:3 }
// arrow function인 경우 return 값이 객체이면 ()로 감싸준다
// method Shorthand
const obj = {
  name : 'foo',
  getName : function() { console.log(this); },
  printName() { console.log(this); }
}
new obj.getName; // __proto__:Object
new obj.printName; // TypeError
console.dir(obj.getName); // prototype 속성이 있음
console.dir(obj.printName); // prototype 속성이 없음
// arrow function과 비슷하다

Object.assign

// jquery $.extends({}. object); 와 동일한 동작
const originalObj = {
  a: 1,
  b: [2, 3, 4],
  c: { d: 5, e: 6 }
};
const copiedObj = Object.assign({}, originalObj);
copiedObj.a = 11;
copiedObj.b[0] = 12;
copiedObj.c.d = 13;
console.log(originalObj); // { a:1, b: [12, 3, 4], c: {d:13 ,e:6} }
console.log(copiedObj); // { a:11, b: [12, 3, 4], c: {d:13 ,e:6} }
// 참조형인 경우 같은 주소를 가지고 있기 때문에 값을 변경하면 원래값에도 영향을 준다, 필요시 deep copy 구현

8. destructuring assignment

const obj = {
    name : 'foo',
    age : 1,
    gender : 'male'
};
const { name, age, gender } = obj;
console.log(name, age, gender); // foo 1 male

// ajax 통신 때 유용함
$.ajax({
  success:function(data){
    const { id, title, detail } = data;
  }
});

9. template literals

console.log(`a
bb
ccc`);
// back-tic 줄바꿈 가능, precode랑 비슷함

10. class

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  toString() {
    return `${this.name}, ${this.age}세`;
  }
  static logNames(...persons) {
    for(const person of persons) {
      console.log(person.name, person.age);
    }
  }
}
class Employee extends Person {
  constructor(name, age, title) {
    super(name, age);
    this.title = title;
  }
  toString() {
    return `${super.toString()}, (${this.title})`;
  }
  static logNames(...persons) {
    for(const person of persons) {
      console.log(person.name, person.age, person.title);
    }
  }
}
const park = new Employee('Park', 35, 'CTO');
const jung = new Employee('Jung', 30, 'CEO');

console.log(park.toString()); // Park, 35세, (CTO)
Person.logNames(park, jung); // Park 35 Jung 30
Employee.logNames(park, jung); // Park 35 CTO Jung 30 CEO

-Class내에 constructor와 method만 가능
-static method는 생성자 함수가 쓰는 메서드 (클래스 메서드)
인스턴스에서는 접근이 안됨, prototype 체인으로 구현을 강제적으로 해도 this 바인딩이 되지 않음
-extends는 상속, super는 Person, sub는 Employee
-super()는 슈퍼 클래스의 생성자를 호출하는 특별한 함수 (Person.constructor())
-super는 ES5로 구현이 안됨, 문법설탕?
ES6 Class는 단지 prototype 상속의 문법설탕일 뿐인가?
-ES5의 inherit 함수에서 superClass는 super를 흉내냄

11. module – import / export

// without 'default' export

// lib.js
export const sqrt = Math.sqrt;
export const square = (x) => { return x * x; }

// main.js
import * as lib from './src/lib';
console.log(lib);
// Object {__esModule: true, sqrt: function, square: function}
console.log(lib.square(5));
console.log(lib.sqrt(4));

import { square, sqrt } from './src/lib';
console.log(square(5));
console.log(sqrt(4));
// with 'default' export

// lib.js
export default function lib() {
  console.log('this is lib default function');
}
export const sqrt = Math.sqrt;
export const square = (x) => { return x * x; }

// main.js
import * as lib from './src/lib';
console.log(lib.default()); // this is lib default function
console.log(lib.square(5));
console.log(lib.sqrt(4));

import lib, { square, sqrt } from './src/lib';
console.log(lib); // function lib() { .. }
console.log(square(5));
console.log(sqrt(4));

https://github.com/react-study/reactStudy/tree/master/02_ES6

ReactJS Setup

맥은 terminal
윈도우는 git bash

ON MAC OSX

0. terminal 열기

1. 패키지 관리자 brew 설치
https://brew.sh

2. node.js 설치
node.js 설치하면 npm이 자동으로 설치됨 (우리가 필요한건 npm)

$ brew install node

3. 프로젝트 폴더 만들기
원하는 디렉토리로 이동해서 프로젝트 폴더 만들기

$ mkdir [folder_name] // 디렉토리 생성
$ cd [folder_name] // 디렉토리 이동
$ ls // 파일 목록 확인
$ rm [file_name] // 파일 삭제

4. npm으로 package 설치
https://docs.npmjs.com/cli/install
4-1. 프로젝트 폴더로 이동해서 npm 설정하기

$ npm init

설정 물음에 적절하게 답하거나 또는 그냥 엔터치면 디폴트값으로 생성됨
완료 후 package.json 파일 생성됨 package-lock.json 파일은 캐싱같은 존재
패키지를 설치하면 node_modules 폴더가 자동으로 생성되고 해당 패키지가 들어있음

4-2. 필요한 패키지 설치하기

$ npm install jquery // npm i jquery
$ npm uninstall jquery // npm un jquery
$ npm i --save jquery // npm i -S jquery
$ npm i --save-dev jquery // npm i -D jquery

npm install saves any specified packages into dependencies by default.
–save (dependencies) –save-dev (devDependencies)
–save is used to save the package required for the application to run
–save-dev is used to save the package for development purpose
–save는 배포용 –save-dev는 개발용

4-3. package.json 설정대로 패키지 설치

$ npm install

만약 다른 프로젝트의 패키지 설정 가이드인 package.json파일을 가지고 있는 경우, 설정 파일에 따라 동일한 패키지가 설치된다

5. babel 설치
https://babeljs.io
ES6를 ES5로 변환해주는 컴파일러
5-1. babel관련 필요한 패키지 설치

$ npm i -D babel-core
$ npm i -D babel-loader
$ npm i -D babel-preset-env
$ npm i -D babel-preset-react

5-2. .babelrc 이라는 숨김파일 만들기

// .babelrc
{
  "presets": [
    ["env", { "modules": false }],
    "react"
  ]
}

#presets-official-presets
env – 표준 모두 ES2015, ES2016, ES2017 모두

$ ls - al // 전체 파일목록 확인
$ cat .babelrc // 해당 파일 내용 보기

6. react 설치

$ npm i -D react
$ npm i -D react-dom

react.js – 핵심기술
react-dom.js / react-native.js (역할분리)

7. sass 설치
sass loader

$ npm i -D node-sass
$ npm i -D sass-loader
$ npm i -D style-loader
$ npm i -D css-loader
$ npm i -D extract-text-webpack-plugin

8. webpack 설치
https://webpack.js.org
모듈 번들러
8-1. webpack 설치

$ npm i -D webpack
$ npm i -D webpack-dev-server

8-2. package.json에 명령어 추가

//----- package.json -----
"scripts": {
    "build": "webpack",
    "devserver": "webpack-dev-server --open --progress"
}

8-3. webpack.config.js 작성

//----- webpack.config.js -----
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    entry: [
        './src/index.js',
        './src/index.scss'
    ],
    output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/dist/',
        filename: 'bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                include: path.join(__dirname),
                exclude: /(node_modules)|(dist)/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin('bundle.css')
    ]
};

8-4. webpack 실행

$ npm run devserver // 서버 실행
$ npm run build // 배포

http://localhost:8080/

https://github.com/katekim1029/react.study/tree/00_default

ReactJS Study #1

#1 개발환경세팅

mac terminal
window git bash

FE 관련 알뜰신잡
웹프론트엔드 개발을 위한 자동화 툴

1. package manager
bower
npm – node package manager
yarn – react 진영에서 밀고 있음

2. build system
grunt – 배포 자동화 (매우 어려움)
gulp – pipe (어려움)
yeoman/yo – boilerplate template engine

3. module bundler
browserify
rollup
webpack – gulp가 하는 대부분의 일을함, 번들링부터 배포까지 가능하게 만들어줌
(js, css, png, json, sass에서 css 변환)

– js 빌드 과정
uglify – js 파일 최적화
concat – 여러파일을 병합
파일의 충돌을 막기 위해 기존에 수동으로 사용하던 방식은 네임스페이스 또는 즉시실행함수

– js 모듈화 작업
CommonJS – node에서 채택
AMD (requirejs) – asynchronous module definition
UMD – universal module definition

CommonJS와 AMD
JavaScript 모듈화 도구, webpack

COMMAND

$ ls - al
$ cd ../
$ mkdir <folder_name> // typing + tab key
$ cat <file_name>
$ clear
$ rm -rf node_modules/ (remove recursive, rimraf)

$ git --version
$ which git
$ git config --global user.name "test"
$ git config --global user.email "test@example.com"
$ npm ls
$ npm init
$ npm install jquery // npm i jquery
$ npm uninstall jquery // npm un jquery
$ npm i --save jquery // npm i -S jquery
$ npm i --save-dev jquery // npm i -D jquery
$ npm i -D babel-{core, preset-{react, env}}
$ npm i -D babel-core, babel-preset-react, babel-preset-env
$ npm i
$ npm i --global babel-cli // npm i -g babel-cli
$ babel test.js
$ babel test.js -d dist
$ npm un -g babel-cli
$ npm i -D babel-loader
$ npm i -D babel-core
  • node.js만 설치하면 npm 자동으로 설치
  • package.json – 프로젝트 규약 (협업시 유용)
  • package_lock.json – 캐싱 파일 같음
  • $ npm install (package.json에 있는 모듈을 모두 설치)
    (dependencies / devDependencies)
    devDependencies – 개발시에 필요하고 배포할 때 불필요한 모듈 (예를 들어 babel)
  • 설치 중 취소할 때 – control + C

BABEL
javascript compiler from ES6 to ES5

$ npm i -D babel-core
$ npm i -D babel-loader
$ npm i -D babel-preset-env
$ npm i -D babel-preset-react
$ npm i -D babel-preset-stage-1

// .babelrc
{
	"presets" : ["env", "stage-1"]
}

#presets-official-presets
env – 표준 모두 ES2015, ES2016, ES2017 모두 (It won’t include stage-x plugins)
stage-1 – proposal (TC39)

REACT

$ npm i -D react
$ npm i -D react-dom
$ npm i -D react-hot-loader // 자동 갱신

What is the difference using webpack-hot-middleware and using this react-hot-loader

WEBPACK

$ npm i -D webpack
$ npm i -D webpack-dev-server
$ npm i -D webpack-hot-middleware

webpack command

//----- webpack.config.js -----
module.exports = {
  entry: './main.js',                 // 진입파일
  output: {                           // 결과파일
    path: __dirname,
    filename: 'bundle.js'
  },
  context: __dirname,
  devtool: 'eval',                    // 개발용 디버깅 기능
  // cheap-module-eval-source-map 원본처럼 보여 디버깅 편리, 용량 문제로 배포할 때 선호하지 않음
  module: {
    rules: [                          // 모듈별 핸들링 정의
      {
        test: /\.js$/,                // 조건 설정
        exclude: [ /node_modules/ ],  // 제외할 경로
        // include: [ /src/ ],        // 포함할 경로
        loader: 'babel-loader'        // 적용할 로더
      }
    ]
  },
  resolve: {
    modules: [ __dirname, 'node_modules' ],
    extensions: [ '.js' ]
  }
}
// webpack cli
// Watch mode --watch
// Watches all dependencies and recompile on change
$ webpack --watch // webpack -W

CLI에서 webpack 쓰지 않고 package.json에서 설정하는 방법

// package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack -w",
    "build": "webpack --colors --profile"
}

// command
$ npm run test
$ npm run start // $ npm start는 기본 지정되어 있음
$ npm run build

webpack.config.js를 개발용 배포용으로 나눠서 실행할 수 있음

"scripts": {
    "start": "webpack -w --config webpack.config.dev.js",
    "build": "webpack -w --config webpack.config.prod.js"
}

https://github.com/react-study/reactStudy/tree/master/01_Setting

ReactJS Study

ReactJS Study 기초부터 실전까지, 7기 by GOMUGOM
– 일정 : 2017년 7월 22일 ~ 9월 23일까지
– 시간 : 매주 토요일 오전 10시 – 오후 1시 (주 1회 / 3시간씩)

1) 개발환경세팅
git
node / npm
package.json
babel
webpack

2) ECMA Script 2015 (ES6)
block scope
let / constants
arrow function
spread operator
rest parameter
computed property key
template literals
class
modules

3) ReactJS 기초 1
component
jsx 문법
props / state / refs
부모/자식 component간의 통신
react devtool

4) ReactJS 기초 2
component lifecycle
event handling
prop types
stateless component

5) todo App 만들기 1
todo App 작성

6) todo App 만들기 2
ajax 호출 및 promise
성능 최적화 1: optimistic update
성능 최적화 2 : immutability helper

7) todo App 만들기 3
react-router

8) Redux 1
Redux
Redux devtool
간단한 redux 예제 작성

9) Redux 2
redux middleware – thunk

10) todo App 만들기 4
todo App을 redux 체계로 전환