[React 교과서] 3장 JSX

리엑트 교과서를 정리한 내용입니다.

3.1 JSX의 정의와 장점

함수 호출과 객체 생성을 위한 문법적 편의를 제공하는 자바스크립트의 확장. JSX가 React에 필수적이지는 않지만 같이 사용할것이 권장됨

  • 개발자 경험 개선: 코드를 읽기 쉽다
  • 팀의 생산성 향상: HTML과 비슷하여 친숙함
  • 문법 오류와 코드량 감소

  • JSX코드 예제

    1
    2
    3
    4
    5
    <div>
    <HelloWorld/>
    <br/>
    <a href = "https://eunii.github.io"> eunii blog</a>
    </div>
  • 위의 코드 자바스크립트로 변경한 예제

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    React.createElement(
    "div",
    null,
    React.createElement(HellowWorld, null),
    React.createElement("br", null),
    React.createElement(
    "a",
    {href : "https://eunii.github.io"},
    "eunii blog"
    ),
    )

자바스크립트 코드 사이에 <>가 있으면 처음에는 어색하지만. React.createBlement(NAME, …) 대신 을 사용하는것이 훨씬 직관적이고 편리하다.
JSX를 사용하려면 브라우저에서 실행하기 전에 컴파일 또는 트랜스파일 과정을 거쳐 일반적 자바스크립트 파일로 변환해야한다.

3.2 JSX의 이해

3.2.1 JSX로 React 엘리먼트 생성하기

1
2
3
4
5
React.createElement(
name,
{key1: value1, key2: vlaue2, ...},
child1, child2, ..., childN
)

위의 코드를 JSX로 바꾸면 아래와 같다

1
2
3
4
5
6
<name key1=value1 key2 value2 ...>
<child1/>
<child2/>
...
<childN/>
</name>

계속 공부해 왔던 HelloWorld예제를 자바스크립트로 작성하면

1
2
3
4
ReactDOM.render(
React.createElement('h1', null, 'Hello world!'),
document.getElementById('content')
)

위의 코드를 JSX로 작성하면

1
2
3
4
ReactDOM.render(
<h1>Hello world!</h1>
document.getElementById('content')
)

JSX문법으로 작성한 객체도 변수에 저장 가능하다.

harmony
1
2
3
4
5
let helloWorldReactElement = <h1>Hello world!</h1>
ReactDOM.render(
helloWorldReactElement,
document.getElementById('content')
)

3.2.2 React 컴포넌트에 JSX 사용하기

JSX 태그는 표준 HTML 태그 이름이기도 하다. 컴포넌트를 다룰 때에도 같은 문법을 사용하고 컴포넌트 클래스 이름이 대문자로 시작한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

- JSX를 이용해서 생성한 HelloWorld클래스
```js
class HelloWorld extends React.Component{
render(){
return(
<div>
<h1> 1. Hello world!</h1>
<h2> 2. Hello world!</h1>
</div>
)
}
}
ReactDOM.render(
<HelloWorld/>
document.getElementById('content')
)

3.2.3 JSX에서 변수 출력하기

컴포넌트를 작송할때, 약간의 코드로 자체적으로 뷰를 변경할 수 있는 코드를 만들기. ex) 현재 시간/날짜를 사용하기
JSX없이 React만 사용하면 +를 이용해 연결하거느 ‘와 ${varName}로 표시한 문자열 탬플릿을 사용할 수 있다. (템플릿 리터럴)

1
2
3
4
5
6
class DateTimeNow extends React.Component{
render(){
let dateTimeNow = new Date().toLocaleDateString()
return <span> Hello {this.props.userName}, current date and time is {dateTimeNow}.</span>
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
let helloWorldReactElement = <h1>Hello world!</h1>
class HelloWorld extends React.Component {
render() {
return <div>
{helloWorldReactElement}
{helloWorldReactElement}
</div>
}
}
ReactDOM.render(
<HelloWorld/>,
document.getElementById('content')
)

3.2.4 JSX에서 속성 사용하기

사용자 계정에 연결할 컴포넌트를 만들때, href와 title의 값은 사용자에 따라 달라져야 하므로 하드 코딩할 수 없다.

1
2
3
4
5
6
7
8
9
10
11
12
class ProfileLint extends React.Component{
render(){
return (
<a href ={this.props.url}
title ={this.props.lable}
target="_blank">
Profile
</a>

)
}
}

위의 코드에서 속성값은 ProfileLink 생성시에 정의된다. ProfileLink를 생성하는 부모 컴포넌트에서 이 값을 전달함.

1
<ProfileLink url='/user/azat' label='Profile for azat' />

가끔 사용자 지정 데이터를 속성으로 추가할 때가 있다. DOM요소에 속성으로 넣는것은 흔히 사용하지만 HTML 비표준 속성에 데이터를 저장하는 것은 안티패턴으로 여겨진다.
DOM에서 데이터를 가져오는것은 메모리 상의 가상 저장소에서 데이터를 가져오는것보다 느리다.

데이터를 반드시 HTML요소의 속성으로 저장해야 하는 경우는 data-*속성을 사용한다.

1
<li data-react-is-awesom={this.reactIsAwesome}> React is awesome!</li>

위의 경우reactIsAwesome 값이 true라면 아래와 같이 HTML이 렌더링 된다

1
<li data-react-is-awesom="true"}> React is awesome!</li>

하지만 아래와 같이 비표준 HTML속성을 전달하면 HTML속성이 렌더링 되지 않는다.

1
2
<li react-is-awesom={this.reactIsAwesome}> React is awesome!</li>
<li reactIsAwesom={this.reactIsAwesome}> React is awesome!</li>

위의 결과는 아래와 같다

1
2
<li> React is awesome!</li>
<li> React is awesome!</li>

아것대신 this.props를 통해서 입력한데이터는 모든 속성에 접근할 수 있다. 모든 속성을 전달해야 한다면 …를 사용할 수 있다.({…this.props)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class HelloWorld extends React.Component {
render() {
return <h1 {...this.props}>Hello {this.props.frameworkName} world!!!</h1>
}
}

ReactDOM.render(
<div>
<HelloWorld
id='ember'
frameworkName='Ember.js'
title='A framework for creating ambitious web applications.'/>
<HelloWorld
id='backbone'
frameworkName='Backbone.js'
title='Backbone.js gives structure to web applications...'/>
<HelloWorld
id='angular'
frameworkName='Angular.js'
title='Superheroic JavaScript MVW Framework'/>
</div>,
document.getElementById('content')
)

3.2.5 React 컴포넌트 메서드 생성하기

React 컴포넌트에 애플리케이션을 위한 메서드를 자유롭게 추가할 수 있다.

1
2
3
4
5
6
7
8
9
class Content extends React.Component {
getUrl(){
return 'http://webapplog.com'
}

render(){
...
}
}

{}안에 클래스 메서드를 호출 하는 방식으로 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
class Content extends React.Component {
getUrl() {
return 'http://webapplog.com'
}
render() {
return (
<div>
<p>Your REST API URL is: <a href={this.getUrl()}>{this.getUrl()}</a></p>
</div>
)
}
}

3.2.6 JSX의 if/else처리

  • 유저 세션에 따른 렌더링 처리 예시(자바스크립트)
    1
    2
    3
    4
    5
    6
    7
    ...
    render(){
    if(user.session)
    return <a href="/logout"> Logout</a>
    else
    return <a href="/login"> Login</a>
    }

JSX로 3가지 방법 표현법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//방법1 변수
render(){
let link
if(this.props.user.session){
link = <a href="/logout"> Logout</a>
else
link = <a href="/login"> Login</a>
return <div>{link}</div>
}
}

// 방법 2 표현식
render(){
let link = (sessionFlag) => {
if(sessionFlag){
return <a href="/logout"> Logout</a>
else
return <a href="/login"> Login</a>
}
return <div>{link(this.props.user.session})}</div>
}

//방법 3 삼항연산자
render(){
return(
<div>
{(this.props.uwer.session)
? <a href="/logout"> Logout</a>
: <a href="/login"> Login</a>
}
</div>
)
}

  • return 문 이전에 JSX 외부에 변수를 선언한 후 JSX 내부에서 {}를 사용하여 출력한다
  • return 문 이전에 JSX외부에서 값을 반환하는 함수 표현식을 선언한 후 JSX내부의 {}에서 실행한다
  • 삼항연산자를 사용한다
  • JSX 내부에서 즉시 실행함수를 사용한다.

3.2.7 JSX의 주석 작성 방법

일반 자바스크립트 주석과 비슷하다. {}로 감싸서 작성한다.

3.3 Babel을 이용한 JSX 트랜스 파일러 설정하기

JSX파일을 자바스크립트코드로 변환하는 과정을 트랜스파일레이션이라고 한다.

  • Babel 명령줄 인터페이스 도구
  • Node.js 또는 브라우저 자바스크립트로 작성한 스크립트(API방식): babel-core 패키지를 이용해서 스크립트를 직성해 변환하는 방식
  • 빌드 도구: Grunt, Gulp, Webpack도구에서 Babel을 플러그인으로 사용할 수 있다.

1. Node.js npm 설치

3.4 React와 JSX의 까다로운 부분

태그를 닫을 때 반드시 /를 넣어야 한다.

3.4.1 특수문자

HTML엔터티코드를 사용하여 저작권 표시나 말바꿈표 따옴표 등을 사용할 수 있다.

  • 1
    - ```mdash;
  • 1
    2
    3
    4

    ```js
    <span>&copy;&mdash;&ldquo;</span>
    <input value ="&copy;&mdash;&ldquo;"/>

아래 코드는 작동하지 않는 오류 코드

1
2
3
var specialChars = "&copy;&mdash;&ldquo;"
<span>{specialChars}</span>
<input value={specialChars}/>

위험한 HTML구문에 대해서 자동으로 이스케이프를 적용함. 특수문자를 노출하려면 다음 방법중 하나를 선택한다.

  • 배열로 출력해 여러개의 분자열로 분리
  • 소스코드에 특수문자를 직접 복사해서 넣는다
  • 특스문자를 \u로 시작하는 이스케이프 시퀸스로 바꾼 후에 유니코드번호를 찾아 사용한다.
  • String.fromCharCode(charCodeNumber)를 이용해서 유니코드 번호에서 문자로 변경한다
  • React 엘리먼트의 _html에 dangerouslySetInnerHTML을 이용하는 방법이 있으나 추천하지 않는다

[React 교과서] 2장 React 첫걸음

리엑트 교과서를 정리한 내용입니다.

엘리먼트는 컴포넌트의 인스턴스이며 컴포넌트 클래스라고 한다.

2.1 엘리먼트 중첩

여러개 엘리먼트가 중첩되는 경우가 많다.
ReactDOM.render()에는 하나의 React엘리먼트만 인자로 전달할 수 있다.
동일한 DOM객체에 두개의 h1태그를 렌더링해야 하는 경우 두 요소를

``````으로 감싸 사용
1
2
3
4
5
6
7
```js
var h1 = React.createElement('h1', null, 'Hello world!') //-h1요소를 생성하여 변수에 담음
var div = React.createElement('div', null, h1,h1) //-세번째 이후 매개변수가 문자열이 아니면 새로 생성하는 엘리먼트의 자식 엘리먼트다.
ReactDOM.render( //h1요소를 ID가 content인 실제 DOM에 랜더링함
div,
document.getElementById('content')
)

createElement 의 첫번째 매개변수에는 아래 두가지 자료형을 입력할 수 있다.

  • 문자열로 작성한 일반적 HTML태그. 소문자로 작성 ex) ‘h1’, ‘div’
  • React 컴포넌트 객체, HelloWorld를 예로 들 수 있음. React 컴포넌트 객체이름은 대문자로 시작한다.

2.2 React컴포넌트 클래스 생성

컴포넌트 클래스(component class)를 사용하면 기능을 느슨하게 결합된 부분으로 분리하여 코드를 재사용할 수 있다.
‘Hello world!’를 별도의 클래스로 분리하는 방법.

class HelloWorld extends React.Component로 상속받아 사용

1
2
3
4
5
6
7
8
9
10
let h1 = React.createElement('h1', null, 'Hello world!')
class HelloWorld extends React.Component {
render() {
return React.createElement('div', null, h1, h1)
}
}
ReactDOM.render(
React.createElement(HelloWorld, null),
document.getElementById('content')
)

여기서 render()는 엘리먼트 하나만 반환함

Hello world!를 여러번 노출해야하면 아래와 같이 클래스 재사용 가능

1
2
3
4
5
6
7
8
9
ReactDOM.render(
React.createElement(div,
null,
React.createElement(HelloWorld),
React.createElement(HelloWorld),
React.createElement(HelloWorld)
),
document.getElementById('content' )
)

2.3 React 속성(props) 사용하기

컴포넌트의 속성(properties)은 React선언형 스타일의 기초다.

1
React.createElememt('a', {href: 'https://eunii.github.io'})

속성은 컴포넌트 내부에서는 변경할 수 없는 값이다.
부모 컴포넌트가 자식 생성 시점에 속성을 할당한다.

속성은 아래와 같은 용도로 사용가능

  • 일반적 HTML 요소의 속성: href, title, style, class
  • React 컴포넌트 클래스의 자바스크립트코드에서 this.props의 값. 예를 들어 this.props.PROPERTY_NAME
    render()메서드에서 입력하여 렌더링하거나 코드에서 활용 할 수 있다.

HelloWorld컴포넌트에 아래 세가지 속성을 추가한다.

  • id
  • frameworkHame
  • title
    id와 title은 h1의 표준속성과 일치에서 랜더링하고 frameworkName은 랜더링 하지 않는다.

h1을 구현하기 전에 helloWorld클래스의 속성을 전달해야함.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ReactDOM.render(
React.createElement(
'div',
null,
React.createElement(HelloWorld, {
id: 'ember',
frameworkName: 'Ember.js',
title: 'A framework for creating ambitious web applications.'}),
React.createElement(HelloWorld, {
id: 'backbone',
frameworkName: 'Backbone.js',
title: 'Backbone.js gives structure to web applications...'}),
React.createElement(HelloWorld, {
id: 'angular',
frameworkName: 'Angular.js',
title: 'Superheroic JavaScript MVW Framework'})
),
document.getElementById('content')
)

render()에서 frameworkName속성 사용하기

1
2
3
4
5
6
7
8
9
10

class HelloWorld extends React.Component {
render() {
return React.createElement(
'h1',
this.props, //모든 속성을 자식 엘리먼트에 전달한다.
'Hello ' + this.props.frameworkName + ' world!'
)
}
}

[React 교과서] 1장 React 살펴보기

리엑트 교과서를 정리한 내용입니다.

1.1 React란 무엇인가?

  • 페이스북에서 만든 자바스크립트 기반의 UI 컴포넌트 라이브러리.

1.2 React가 해결할 수 있는 문제

  • DOM을 매번 새로 생성하기 위해 UI를 함수로 만들었다.

1.3 React의 장점

  • 단순한 앱 개발
  • 빠른 UI
  • 코드량 감소

1.3.1 간결성

  • 선언형 스타일 채택
  • 순수한 자바스크립트를 이용한 컴포넌트 기반 아키텍쳐
  • 강력한 추상화

선언형 스타일 채택

선언형 스타일의 장점은 간단하고 가독성이 좋다. 결과값에 더 집중했다.
뷰에 변경이 발생하는경우 react가 알아서 갱신.

  • 명령형 코드 예시
    1
    2
    3
    4
    5
    6
    var arr =[1,2,3,4,5],
    arr2 = []
    for (var i=0; i<arr.length; i++){
    arr2[i] = arr[i]*2
    }
    console.log('a',arr2)

결과창

1
a [2,4,6,8,10]

  • 선언형 코드 예시
    1
    2
    3
    var arr = [1,2,3,4,5]
    arr2 = arr.map(function(v,i){ return v*2 })
    console.log('b', arr2)

결과창

1
b [2,4,6,8,10]

자바스크립트를 이용한 컴포넌트 기반 아키텍처

코드 재사용이 쉬워 코드를 줄일 수 있다.

  • 코드 예시
    1
    2
    if (user.session) return React.createElement('a',{hret: '/logout'}, 'Logout')
    else return React.createElement('a', {href:'/login'}, 'Login')

강력한 추상화

내부 인터페이스를 숨기고 정규화 과정을 거친 합성 메서드와 속성을 제공한다.

1.3.2 속도와 테스트 용이성

가상 DOM은 자바스크립트 메모리에만 존자한다. 데이터 변경시 가상 DOM을 머저 비교하고 랜더링이 필요한 경우애만 실제 DDM에 랜더링 한다.
필요한 부분반 갱신함.

1.3.3 React의 폭넓은 개발 커뮤니티와 생태계

  • React 컴포넌트 목록: 1
    [2](http://devarchy.com/react-components)  
    

등등..

1.4 React의 단점

  • AngularJS나 Ember같은 기능을 사용하려면 라이브러리를 함꼐 사용해야함
  • 다른 프레임워크만큼 성숙하지 않음.-> 핵심 API가 조금씩 바뀜
  • 관련 자료가 부족
  • 단방향 데이터 바인딩만 제공
  • 리액티브 프로그래밍은 아니다.

1.5 웹 애플리케이션에 React적용하기

  • UI 라이브러리로 React와 관련된 Reduz나 React Router를 활용한 단일 페이지 애플리케이션 스택의 구성
  • MVC의 V를 대체하는 UI라이브러리로 기존 IVX프레임워크와 결합
  • jQuery 를 기반으로 서버 측 렌더링을 거친 애플리케이션에서 자동완성 등 일부 기능을 위한 UI컴포넌트로 활용
  • 대부분의 로직을 직접처리하는 백엔드에서 서버측 렌더링 탬플릿 라이브러리로 활용
  • 백엔드와 프론트엔드서 모두 자바스크립트를 사용하는 경우
  • React Native를 UI 라이브러리로 사용한 모바일 앱
  • 여러가지 렌더링 대상에 적용할 목적으로 사용하는 UI라이브러리

1.5.1 React 라이브러리와 렌더링 대상

  • UI개발이 필요한 환경에 어디든지 사용할 수 있게 만드는중. ReactDOM.rander()를 사용함(여러 환경에서 사용가능)

1.5.2 단일 페이지 애플리케이션과 React

서버보다는 클라이언트(브라우저)에 로직이 더 많은 팻 클라이언트다. SPA는 HTML렌더링, 입력값 겁증, UI변경 등의 기능을 브라우저에서 해결한다.
SPA 방식으로는 MVC아키텍처를 많이 사용하지만 다른 방식도 있음.

1.5.3 React 개발 스택

모델링,스타일라우팅 등에 정해진 방법이 없어 다른 라이브러리를 결합해 사용한다.

(책 56쪽)

  • 데이터 모젤링과 백엔드
  • 라우팅
  • React용 Bootstrap컴포넌트
  • 날짜 입력 컴포넌트
  • WAI-ARIA정의를 따르는 자동완성컴포넌트

1.6 첫번째 React앱 만들기:Hello World

파일구조
/hello-world
/js
react.js
react-dom.js
index.html

예시 코드는 여기 에서 다운받을 수 있다.

index.html파일 내용

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html>
<head>
<script src="js/react.js"></script>
<script src="js/react-dom.js"></script>
</head>
<body>
<div id="content"></div>
<script type="text/javascript">
</script>
</body>
</html>

React 엘리먼트를 생성하려면 React.createElement(clementName, data, child)를 호출한다

  • elementName : HTML 태그명’h1’처럼 문자열로 작성하거나 직접 만든 컴포넌트 를래스 객체를 넘겨줄 수 있음
  • data: 속성이나 상위컴포넌트에 받는 값으로 null이나{name: Azat} 같은 형태의 데이너
  • child: 자식 엘리먼트나 태그 내부에 작성하는 텍스트
1
2
3
4
5
var h1 = React.createElement('h1', null, 'Hello world!') //-h1요소를 생성하여 변수에 담음
ReactDOM.render( //h1요소를 ID가 content인 실제 DOM에 랜더링함
h1,
document.getElementById('content')
)

아래처럼 변수에 담지 않고 직접 넣어줄수도 있다.

1
2
3
4
5

ReactDOM.render( //h1요소를 ID가 content인 실제 DOM에 랜더링함
React.createElement('h1', null, 'Hello world!')
document.getElementById('content')
)

웹 브라우져에서


Hello world!



객체가 만들어진것을 볼 수 있다.

[React] React 시작하기

1. Nodejs 설치 및 최신 버전 확인(6버전 이상)

  • https://nodejs.org/ko/ 여기서 최신 nodejs를 설치한다.
  • 콘솔 창(window + R -> cmd 검색) 에서 아래와 같이 명령어를 입력하면 내 pc에 깔린 nodejs버전이 나온다.
    1
    node -v

2. 프로젝트를 생성할 폴더 위치로 이동하여 다음과 같이 프로젝트를 시작한다.

아래 명령어로 폴더에 이동후

1
cd d:\dev\react\tutorial

아래 명령어로 프로젝트를 시작한다.

1
2
$ npm install -g create-react-app   
$ create-react-app my-app

3. my-app/src 하위의 파일들을 삭제한다.

1
2
$ cd my-app
$ rm -f src/*

4. my-app/src/index.css 파일을 만들어 아래 내용을 복사한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
body {
font: 14px "Century Gothic", Futura, sans-serif;
margin: 20px;
}

ol, ul {
padding-left: 30px;
}

.board-row:after {
clear: both;
content: "";
display: table;
}

.status {
margin-bottom: 10px;
}

.square {
background: #fff;
border: 1px solid #999;
float: left;
font-size: 24px;
font-weight: bold;
line-height: 34px;
height: 34px;
margin-right: -1px;
margin-top: -1px;
padding: 0;
text-align: center;
width: 34px;
}

.square:focus {
outline: none;
}

.kbd-navigation .square:focus {
background: #ddd;
}

.game {
display: flex;
flex-direction: row;
}

.game-info {
margin-left: 20px;
}

5. my-app/src/index.js 파일을 아래 내용을 복사하여 만든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';


class Square extends React.Component {
render() {
return (
<button className="square">
{/* TODO */}
</button>
);
}
}

class Board extends React.Component {
renderSquare(i) {
return <Square />;
}

render() {
const status = 'Next player: X';

return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}

class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-info">
<div>{/* status */}</div>
<ol>{/* TODO */}</ol>
</div>
</div>
);
}
}

// ========================================

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

6. 아래 명령어로 시작한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

$ npm start
```

## 7. localhost:3000 으로 아래와 같은 화면이 뜬다.

## 8. my-app/src/index.js파일을 열어보면 아래 세가지 컴포넌트로 구성되어 있다.

- Square : 하나의 <button>을 렌더링함
- Board : 9개의 사각형을 랜더링함
- Game : 공백있는 하나의 보드를 랜더링함

## 9. Board 컴포넌트에서 Square 컴포넌트로 데이터(숫자 0~9) 전달하기

### 9.1 index.js파일의 Board클래스 부분을 아래와 같이 변경한다.
```js
class Board extends React.Component {
renderSquare(i) {
return <Square value={i} />;
}

9.2 Square클래스 render 메서드를 아래와 같이 변경한다.

1
2
3
4
5
6
7
8
9
class Square extends React.Component {
render() {
return (
<button className="square">
{this.props.value}
</button>
);
}
}
  • 이렇게 변경해서 저장 후 npm start로 실행해보면 비어있던 9개 사각형 칸에 0~8까지 숫자가 입력되서 나온다.

10. 대화형 컴포넌트 : 빈 사각형을 클릭하면 X표시가 되게 변경하기

10.1 Sqare의 render()함수를 아래와 같이 변경한다.

Square클래스의 생성자에서 this.state을 설정하여 상태(초기값 null)를 가질 수 있게 한다.

1
2
3
4
5
6
7
8
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
}

아래와 같이 render()함수를 변경하면 사각형을 클릭하면 클릭한 빈 사각형안의 값이 X로 바뀐다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}

render() {
return (
<button className="square" onClick={() => this.setState({value: 'X'})}>
{this.state.value}
</button>
);
}
}

11 State에 저장하기

클릭 할때마다 o,x 번갈아 나오게 하고, 승자를 가리기 위해 9개 블럭의 상태를 동시에 확인해야함.
여러 하위 컴포넌트로 부터 데이터를 모으거나, 하위 컴포넌트들이 서로 통신하기 원하면 상위컴포넌트로 state를 이동시킴.
상위 컴포컨트는 props를 통해 하위 컴포넌트로 state를 전달해 줄 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
};
}

renderSquare(i) {
return <Square value={i} />;
}

render() {
const status = 'Next player: X';

return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}

지금 board의 renderSquare매서드는 아래와 같다.

1
2
3
4
renderSquare(i) {
return <Square value ={i} />;

}

Square에 value prop를 전달하도록 수정한다

1
2
3
renderSquare(i) {
return <Square value={this.state.squares[i]} />;
}

1
2
3
4
5
6
7
8
renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
);
}
1
2
3
4
5
6
7
8
9
class Square extends React.Component {
render() {
return (
<button className="square" onClick={() => this.props.onClick()}>
{this.props.value}
</button>
);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
};
}

handleClick(i) {
const squares = this.state.squares.slice();
squares[i] = 'X';
this.setState({squares: squares});
}

renderSquare(i) {
return (
<Square
value={this.state.squares[i]}
onClick={() => this.handleClick(i)}
/>
);
}

render() {
const status = 'Next player: X';

return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145

function Square(props) {
return (
<button className="square" onClick={props.onClick}>
{props.value}
</button>
);
}

class Board extends React.Component {
renderSquare(i) {
return (
<Square
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
/>
);
}

render() {
return (
<div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}

class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
history: [
{
squares: Array(9).fill(null)
}
],
stepNumber: 0,
xIsNext: true
};
}

handleClick(i) {
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[history.length - 1];
const squares = current.squares.slice();
if (calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? "X" : "O";
this.setState({
history: history.concat([
{
squares: squares
}
]),
stepNumber: history.length,
xIsNext: !this.state.xIsNext
});
}

jumpTo(step) {
this.setState({
stepNumber: step,
xIsNext: (step % 2) === 0
});
}

render() {
const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);

const moves = history.map((step, move) => {
const desc = move ?
'Go to move #' + move :
'Go to game start';
return (
<li key={move}>
<button onClick={() => this.jumpTo(move)}>{desc}</button>
</li>
);
});

let status;
if (winner) {
status = "Winner: " + winner;
} else {
status = "Next player: " + (this.state.xIsNext ? "X" : "O");
}

return (
<div className="game">
<div className="game-board">
<Board
squares={current.squares}
onClick={i => this.handleClick(i)}
/>
</div>
<div className="game-info">
<div>{status}</div>
<ol>{moves}</ol>
</div>
</div>
);
}
}

// ========================================

ReactDOM.render(<Game />, document.getElementById("root"));

function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}

[Markdown] Markdown 문법 정리

1. Header

글머리 1 ~ 6

1
2
3
4
5
6
# This is a H1
## This is a H2
### This is a H3
#### This is a H4
##### This is a H5
###### This is a H6

This is a H1

This is a H2

This is a H3

This is a H4

This is a H5
This is a H6

2. 굵게 기울임꼴 텍스트

2.1 굵게 지정하려면 두개의 별표로 묶습니다.

1
This text is **bold**.

This text is bold.

2.2 기울임꼴로 지정하려면 한개의 별표로 묶습니다.

1
This text is *italic*.

This text is italic.

2.3 굵게 기울임꼴로 지정하려면 세개의 별표로 묶습니다.

1
This text is ***bold and italic***.

This text is bold and italic.

3. BlockQuote

1
> This is a BlockQuote

This is a BlockQuote

This is a BlockQuote

This is a BlockQuote

이 안에서도 마크다운 요소를 사용할 수 있습니다.

> - List
> 
1
2
> BlockQuote
>
  • List
    1
    2
    > BlcokQuote
    >

4. List

4.1 순서 있는 목록

어떤 번호를 넣더라도 내림차순으로 숫자가 지정됩니다.

1
2
3
1. 첫번쨰
3. 두번째
2. 세번째

  1. 첫번째
  2. 두번째
  3. 세번째



다른 목록 안에 목록을 중첩하려면 항목을 들여씁니다.

1
2
3
4
1. 첫번쨰
1. 두번째
1. 세번째
1. 네번째
  1. 첫번째
    1. 두번째
    2. 세번째
  2. 네번쨰

4.2 순서 없는 목록

1
2
3
4
5
6
7
8
9
10
11
* 빨강
* 녹색
* 파랑

+ 빨강
+ 녹색
+ 파랑

- 빨강
- 녹색
- 파랑
  • 빨강
    • 녹색
      • 파랑
  • 빨강
    • 녹색
      • 파랑
  • 빨강
    • 녹색
      • 파랑

5. Table

파이프(|) 및 하이픈(-)을 이용하여 테이블을 만들 수 있습니다.
하이픈으로는 헤더를 만들며 파이프로는 각 열을 만듭니다.
하이픈으로 헤더 구분시 좌측에 콜론(:)을 삽입 할 경우 좌측정렬 우측에 삽입 할 경우 우측정렬이 되며 양쪽에 둘 경우 가운데 정렬이 됩니다.

1
2
3
4
5
6
| Fun                  | With                 | Tables          |
| :------------------- | -------------------: |:---------------:|
| left-aligned column | right-aligned column | centered column |
| $100 | $100 | $100 |
| $10 | $10 | $10 |
| $1 | $1 | $1 |
Fun With Tables
left-aligned column right-aligned column centered column
$100 $100 $100
$10 $10 $10
$1 $1 $1

6. 링크

6.1. 참조 링크

syntax:

[id]: Link
[title][id]

1
2
3
4
5
6
[hscodev]: hsco.dev
[github]: https://github.com/hscodev

[블로그][hscodev]

[깃허브][github]

블로그

깃허브

6.2. 인라인 링크

syntax:

[Label](Link)

1
[블로그](https://hsco.dev)

블로그

6.3. 자동연결

syntax:

\

1
<https://hsco.dev>

https://hsco.dev

7. 코드

개발 코드를 코드블록으로 배치 할 수 있습니다.
alias 별칭을 이용하여 구문 강조가 가능합니다.

이름 Alias
java java
json json
javascript javascript
html html
markdown md
SQL sql
1
your code goes in here

8. 이미지

1
2
![Alt text](/assets/images/duck.jpg)
![Alt text](/assets/images/duck.jpg "별그림")

Alt text
Alt text

[자료구조] QuickSort(퀵정렬) - Java

1. QuickSort(퀵정렬)

1.1 퀵정렬 이란?

  1. 배열중에 임의의 한 값을 선택해 그 기준값을 기준으로 작은건 왼쪽, 큰건 오른쪽에 정렬.

문제.2751 [백준] 수 정렬하기 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

public static void main(String[] args) throws NumberFormatException, IOException {

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(br.readLine());
}
br.close();
quickSort(arr);
for (int i : arr) {
System.out.println(i);
}
}

public static void quickSort(int[] arr) {
sort(arr, 0, arr.length - 1);
}

private static void sort(int[] arr, int start, int end) {
if (start >= end)
return;

int mid = partition(arr, start, end);
sort(arr, start, mid - 1);
sort(arr, mid, end);
}

private static int partition(int[] arr, int start, int end) {
int pivot = arr[(start + end) / 2];
while (start <= end) {
while (arr[start] < pivot)
start++;
while (arr[end] > pivot)
end--;
if (start <= end) {
swap(arr, start, end);
start++;
end--;
}
}
return start;
}

private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
  • 4,3,2,1,0 배열을 정렬할때 아래 순으로 졍렬된다.
4 3 2 1 0
0 3 2 1 4
0 1 2 3 4

[자료구조] MeargeSort(병합 정렬) - Java

1. 병합정렬(MeargeSort)

1.1 병합 정렬이란?

  1. 정렬할때 가장 작은 단위로 나눠서 정렬후(sort) 병합(mearge)하는 것을 말한다.

문제.2751 [백준] 수 정렬하기 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

public static void mergeSort(int[] arr) {
mergeSort(arr, 0, arr.length - 1);
}

public static void mergeSort(int[] arr, int start, int end) {

int[] tmp = new int[arr.length];
if (start < end) {
int mid = (start + end) / 2;
mergeSort(arr, start, mid);
mergeSort(arr, mid + 1, end);
mearge(arr, start, mid, end);
}

}

private static void mearge(int[] arr, int start, int mid, int end) {
int[] tmp = new int[arr.length];
for (int i = start; i <= end; i++) {
tmp[i] = arr[i];
}
int part1 = start;
int part2 = mid + 1;
int index = start;
while (part1 <= mid && part2 <= end) {
if (tmp[part1] <= tmp[part2]) {
arr[index] = tmp[part1];
part1++;
} else {
arr[index] = tmp[part2];
part2++;
}
index++;
}

for (int i = 0; i <= mid - part1; i++) {
arr[index + i] = tmp[part1 + i];
}

}

private static void printArray(int[] arr) {
for (int i : arr) {
System.out.println(i);
}

}

public static void main(String[] args) throws NumberFormatException, IOException {

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(br.readLine());
}
br.close();
mergeSort(arr);
printArray(arr);
}
}
  • 4,3,2,1 배열을 정렬할때 아래 순으로 졍렬된다.
4 3 2 1
3 4 2 1
3 4 1 2
1 2 3 4

[SPRING] 6. DI(Dependency injection)

인프런의 자바 스프링 프레임워크(ver.2018) - 신입 프로그래머를 위한 강좌를 보고 정리한 내용입니다.

6. DI(Dependency injection)

6.1 DI(Dependency Injection)란?

  • 배터리 일체형
    1
    2
    3
    4
    5
    6
    7
    public class ElectronicCarToy {
    private Battery battery;

    public ElectroniCarToy(){
    battery = new NormalBattery();
    }
    }

배터리가 떨어지면 장난감 새로 구입해야함

  • 배터리 분리형 1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class ElectronicCarToy {
    private Battery battery;

    public ElectroniCarToy(){

    }

    public void setBattery(Battery battery){
    this.battery = battery;
    }
    }

setBattery()를통해 배터리를 교체 할 수 있다. (처음에 배터리 없는 상태로 출시)

  • 배터리 분리형 2
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class ElectronicCarToy {
    private Battery battery;

    public ElectroniCarToy(Battery battery){
    this.battery = battery;
    }

    public void setBattery(Battery battery){
    this.battery = battery;
    }
    }

setBattery()를통해 배터리를 교체 할 수 있다. (처음에 배터리 있는 상태로 출시)

[SPRING] 1. 스프링 개요

인프런의 자바 스프링 프레임워크(ver.2018) - 신입 프로그래머를 위한 강좌를 보고 정리한 내용입니다.

1. 스프링개요

1.1 스프링프레임워크

스프링프레임워크는 주요기능으로 DI. AOP, MVC, JDBC등을 제공한다.

1.2 스프링 프레임워크 모듈

스프링모듈 기능
spring-core 스프링의 핵심인 DI(Depenency Injection)과 IoC(Inversion of Control)을 제공
spring-aop AOP 구현 기능 제공
spring-jdbc 데이터베이스를 쉽게 다룰 수 있는 기능 제공
spring-tx 스프링에서 제공하는 트랜젝션 관련 기능
spring-webmvc 스프링에서 제공하는 컨트롤러(Controller)와 뷰(View)를 이용한 MVC구현 기능 제공

1.3 스프링 컨테이너(IoC)

스프링에서 객체를 생성하고 조립하는 컨테이너(contatiner)로, 컨테이너를 통해 생성된 객체를 빈(Bean)이라고 부른다.

  1. 객체생성 및 속성 데이터 작성(xml문서)
  2. 스프링컨테이너에서 객체 생성 및 조립
  3. 애플리케이션 구현(개발 문서)

[Hexo와 깃허브로 블로그 만들기] 블로그에 Google Analytics 설치하기

1. 구글 애널리틱스 사이트에 계정만들기

google analytics 회원가입 하러가기

2. GA홈에서 관리할 사이트 계정을 추가한다.

  1. 관리 클릭

  2. 계정만들기 클릭

  3. 정보 넣고 추적ID가져오기 클릭

  1. 추적 아이디 값 복사하기

3. /blog/themes/icarus/_config.yml 파일 수정

1
2
3
plugins:
google-analytics:
tracking_id: XXXXXX (required)

4. 사용자 분석

구글 애널리틱스 사용자 분석하러 가기

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×