SlideShare a Scribd company logo
1 of 57
Download to read offline
컴포넌트 관점에서 개발하기
2017 프론트엔드 트렌드&인사이트
주우영
프런트엔드 개발 시작하기
네이버는 이렇게 한다!, 위키북스
JavaScript Promise
한빛 eBook, 한빛미디어
페이스북 프론트엔드개발 그룹 운영
https://www.facebook.com/groups/webfrontend/
레진엔터테인먼트 프론트엔드개발팀
오늘, 새로운 기술과
기능을 나열하기 보다
현대 UI 개발에 있어 중요히
여기는 부분에 대해 이야기합니다.
현대 프레임워크의 공통된 접근법
컴포넌트 단위로 사고하고 디자인
import {Component} from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>Welcome to {{title}}</h1>
`,
styles: [`
h1 {
font-size: 4em;
}
`]
})
export class AppComponent {
title = 'app';
}
import {Component} from 'react';
const style = {
fontSize: '4em'
};
class HelloMessage extends Component {
static defaultProps = {
title: 'React'
};
render() {
return (
<h1 style={style}>
Welcome to {this.props.title}
</h1>
);
}
}
<style scoped>
h1 {
font-size: 4em;
}
</style>
<template>
<h1>Welcome to {{title}}</h1>
</template>
<script type="text/babel">
export default {
data () {
return {
title: 'Vue'
}
}
}
</script>
<dom-module id="hello-element">
<template>
<style>
h1 {font-size: 4em}
</style>
<h1>Welcome to {{title}}</h1>
</template>
<script>
class HelloElement extends Polymer.Element {
static get is() {return "hello-element";}
constructor() {
super();
this.title = "Polymer";
}
}
customElements.define(HelloElement.is, HelloElement);
</script>
</dom-module>
WHY
COMPONENT?
하나의 문제를 잘 해결하는
COMPONENT
프로그램
새로운 방법이 아닌
예로부터 모든 공학 분야의
공학자가 자주 사용해 오던
문제 해결 방법
Unix Philosophy
Write programs that do one thing and do it well.
Write programs to work together.
Doug Mcllroy, Unix pipeline inventor
The UNIX Philosophy in 9 paramount precepts
Mike Gancarz (a member of the team that designed the X Window System)
Small is beautiful.
Make each program do one thing well.
Write programs handle text streams, because that is a universal interface.
$ ps -ef
Processes Status
Report a snapshot of the current processes
$ grep gradle
Globally search a regular expression and print
Searching plain-text data sets for lines that match a regular expression
$ ps -ef | grep gradle
사고의 분산을 막고 하나의 문제에 집중함으로써
효율적으로 개발할 수 있다
설계의 오류를 쉽게 파악할 수 있고
상대적으로 테스트하기 쉽다
이식성을 높일 수 있고
변경에 유연하게 대체할 수 있다
API
UI는 자주적으로 동작하는 또 다른 프로그램,
그것을 API로 제어한다는 사고로 접근
자바스크립트를 개발할 때 우리는
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
DOM을 직접 핸들링, 장황하고 UI의 형태를 한눈에
파악하기 힘듦
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
상태를 class나 data attr에 설정 및 사용하여
전체적인 상태 흐름을 알기 힘듦
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
DOM API의 비용은 비쌈. 상태 변화를 위해 

DOM API 호출이 남용됨
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
UI 상태 변화를 위한 render 외의 부가적 메서드
다량 정의
프리젠테이션 로직은 크고 복잡.
테스트하고 유지보수하기 괴롭다
Functional Programming
컴포넌트 접근법은 함수형 프로그래밍하고도 관련이 깊다
부작용(Side effect)없이 하나의 일을 잘 수행하는 함수
그러한 함수를 조합 / 구성함으로써 큰 문제를 해결
F2 F3 F4 F5F1
{

“type”: “oval”,

“size”: 32

}
Functional Programming and UI Component
View = Function(state)
function Header({title, desc}) {
return (
<header className="header">
<div className="header__inner">
<h1 className="header__title">{title}</h1>
<p className="header__description">{desc}</p>
</div>
</header>
);
}
View = Function(state)
REMEMBER
Header({
title: 'Hello World!',
desc: 'This is Awesome.'
});
<header class="...">
<div class="...">
<h1 class="...">Hello World!</h1>
<p class="...">This is Awesome.</p>
</div>
</header>
<header class="...">
<div class="...">
<h1 class="...">Hello World!</h1>
<p class="...">This is Awesome</p>
</div>
</header>
<header class="...">
<div class="...">
<h1 class="...">Welcome</h1>
<p class="...">This is Awesome</p>
</div>
</header>
Equal?
<header class="...">
<div class="...">
<h1 class="...">Hello World!</h1>
<p class="...">This is Awesome</p>
</div>
</header>
<header class="...">
<div class="...">
<h1 class="...">Welcome</h1>
<p class="...">This is Awesome</p>
</div>
</header>
Equal?
<header class="...">
<div class="...">
<h1 class="...">Hello World!</h1>
<p class="...">This is Awesome</p>
</div>
</header>
<header class="...">
<div class="...">
<h1 class="...">Welcome</h1>
<p class="...">This is Awesome</p>
</div>
</header>
Equal? FAIL
Snapshot Testing with Jest
HTML(TMPL), CSS, 자바스크립트를 분리하는게
당연한 관심사의 분리라고 생각
과거 우리는.
Templates separate technologies, not concerns.
템플릿은 기술의 분리일 뿐 관심사의 분리가 아니다.
Pete Hunt, React developer
페이트 헌트, 리액트 개발자
“
”
KingCard Component
중요한건 해결하고자 하는 문제
같은 문제를 해결한다면 관심사는 같다
이때, 분리된 환경 보다
한 곳에 있는 경우가 훨씬 수월하다
관심사가 같다면 수정 시,
함께 수정해야 할 확률이 높다
HTML, CSS를 어떻게든 셋팅한 후
자바스크립트를 이어서 테스트
UI 테스트에 대한 자원 준비 없이
곧바로 컴포넌트를 테스트
Test IconText Component
it('iconDirection 속성에 left를 지정하면 아이콘이 좌측에 배치된다.', () => {
// Given
// When
const wrapper = shallow(
<IconText
label="친구초대"
icon="add-friend"
iconDirection="left"
/>
);
// Then
const children = wrapper.children('.icon-text__inner').children();
expect(children.first()).to.have.className('icon-text__icon');
expect(children.last()).to.have.className('icon-text__label');
});
"## Header
$ "## Header.js
$ "## Header.test.js
$ %## style.scss
"## TallCard
$ "## TallCard.js
$ "## TallCard.test.js
$ %## style.scss
"## KingCard
$ "## KingCard.js
$ "## KingCard.test.js
$ %## style.scss
%## StickyBar
"## StickyBar.js
"## StickyBar.test.js
%## style.scss
따라서 관련있는 것은
최대한 가까이에 두는
구조가 현재 유행
const Button = (props) => (
<button className={'large' in props && 'large'}>
{props.children}
<style jsx>{`
button {
padding: 20px;
background: #eee;
color: #999
}
.large {
padding: 50px
}
`}</style>
</button>
);
또는 하나의 파일 내 모든 관심사를
작성하는 방식도 선호
뭘 좀 만들어 봅시다.
이런 UI를 개발해 달라고 했을때
가장 먼저 한가지 일을 수행하는
최소 단위를 분석
뭘 좀 만들어 봅시다.
이런 UI를 개발해 달라고 했을때
가장 먼저 한가지 일을 수행하는
최소 단위를 분석
뭘 좀 만들어 봅시다.
이런 UI를 개발해 달라고 했을때
가장 먼저 한가지 일을 수행하는
최소 단위를 분석
뭘 좀 만들어 봅시다.
이런 UI를 개발해 달라고 했을때
가장 먼저 한가지 일을 수행하는
최소 단위를 분석
<TallCard/>
를 만들어 봅시다.
BEM(Block, Element, Modifier)
컴포넌트와 어울리게 마크업하기
Block
애플리케이션의 구성 요소로서 독립된 존재
Element
블록을 구성하는 작은 단위 또는 자식 개체
Modifier
블록이나 요소의 테마, 동작을 표현
Block
TallCard
Element
Information
Modifier
BadgeUp
Thumbnail
tall-card
tall-card__badge
tall-card__badge-up
tall-card__thumbnail
tall-card__image
tall-card__information
tall-card__title
tall-card__meta
tall-card__meta-key
tall-card__meta-value
BEM tree
BEM(Block, Element, Modifier)
컴포넌트와 어울리게 마크업하기
<div class="tall-card tall-card_badge_up">
<div class="tall-card__badge">
<i class=“tall-card__badge-up">
<span class="blind">UP</span>
</i>
</div>
<div class="tall-card__thumbnail">
<img class="tall-card__image" src="" alt=""/>
</div>
<div className="tall-card__information">
<h5 className="tall-card__title">레바툰</h5>
<dl class="tall-card__meta">
<dt class=“tall-card__meta-key">장르</dt>
<dd class=“tall-card__meta-value">개그 / 일상</dd>
<dt class=“tall-card__meta-key">작가</dt>
<dd class=“tall-card__meta-value">레바</dd>
</dl>
</div>
</div>
Markup with BEM
const TallCard = ({title, image, badge, metadata = []}) => (
<div className={`tall-card ${badge === 'up' ? ‘tall-card_badge_up' … `}>
<div className="tall-card__badge">
<i className=“tall-card__badge-up”/>
</div>
<div className="tall-card__thumbnail">
<img className="…" src={image} alt={`${title}의 썸네일`}/>
</div>
<div className="tall-card__information">
<h5 className="tall-card__title">{title}</h5>
{metadata.length > 0 ? (
<dl className=“tall-card__meta">
${metadata.map(({key, value}) => ([
<dt className=“tall-card__meta-key">{key}</dt>,
<dt className=“tall-card__meta-key">{value}</dt>
]))}
</dl>
) : null}
</div>
</div>
);
Create React Component
$module: 'icon-text';
.#{$module} {
&__badge {
/*...*/
&__up {/*...*/}
}
&__thumbnail {
/*...*/
&__image {/*...*/}
}
&__information {/*...*/}
&__title {/*...*/}
&__meta {/*…*/}
&__meta-key {/*...*/}
&__mata-value {/*...*/}
}
Styling with SASS
SASS의 interpolation은
컴포넌트 접근법과 잘 어울린다
스타일링 영역을 문법적으로
명확히 표현할 수 있다
"## TallCard
"## TallCard.js
%## TallCard.scss
"## TallCard
"## TallCard.js
"## TallCard.html
%## TallCard.scss
File structure
마크업 코드를 템플릿으로 분리한 경우
마크업을 자바스크립트에 포함한 경우
Context Free
<CardGroup/><SquareCard/> type = subscriptions
상위 컴포넌트 스타일이 하위 컴포넌트 스타일에 영향을 주면 안된다
컴포넌트는 어떤 문맥에서든 자유로워야 한다
badge = up sensational = true
만약 특정 문맥에서 컴포넌트가 변화한다면 해당 컴포넌트에
Context Free
<SquareCard/>
badge = new
새로운 변환자(Modifier)를 추가한다
Context Free
<CardGroup/>
CardList 컴포넌트는 badge가 up인 SquareCard 컴포넌트를
자식 컴포넌트로 포함하고 있을 뿐이다
type = subscriptions
타인의 잣대에 얽매이면 행복할 수 없듯
컴포넌트 역시 특정 문맥에 얽매이면
행복할 수 없다
감사합니다.

More Related Content

What's hot

[140315 박민근] 젠킨스를 이용한 자동빌드 시스템 구축하기(ci)
[140315 박민근] 젠킨스를 이용한 자동빌드 시스템 구축하기(ci)[140315 박민근] 젠킨스를 이용한 자동빌드 시스템 구축하기(ci)
[140315 박민근] 젠킨스를 이용한 자동빌드 시스템 구축하기(ci)MinGeun Park
 
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceKGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceXionglong Jin
 
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019devCAT Studio, NEXON
 
[D2 오픈세미나]1.무한스크롤성능개선
[D2 오픈세미나]1.무한스크롤성능개선[D2 오픈세미나]1.무한스크롤성능개선
[D2 오픈세미나]1.무한스크롤성능개선NAVER D2
 
서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)수보 김
 
[AWSKRUG] 혼자서 커뮤니티 귀동냥하며 만든 Next.js & Amplify & serverless framework 서버리스 웹 플...
[AWSKRUG] 혼자서 커뮤니티 귀동냥하며 만든 Next.js & Amplify & serverless framework 서버리스 웹 플...[AWSKRUG] 혼자서 커뮤니티 귀동냥하며 만든 Next.js & Amplify & serverless framework 서버리스 웹 플...
[AWSKRUG] 혼자서 커뮤니티 귀동냥하며 만든 Next.js & Amplify & serverless framework 서버리스 웹 플...Tae-Seong Park
 
웹을 지탱하는 기술
웹을 지탱하는 기술웹을 지탱하는 기술
웹을 지탱하는 기술JungHyuk Kwon
 
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018devCAT Studio, NEXON
 
게임 서버 성능 분석하기
게임 서버 성능 분석하기게임 서버 성능 분석하기
게임 서버 성능 분석하기iFunFactory Inc.
 
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균NAVER D2
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 Yong Joon Moon
 
C# Game Server
C# Game ServerC# Game Server
C# Game Serverlactrious
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010devCAT Studio, NEXON
 
파이썬 생존 안내서 (자막)
파이썬 생존 안내서 (자막)파이썬 생존 안내서 (자막)
파이썬 생존 안내서 (자막)Heungsub Lee
 
[오픈소스컨설팅] 프로메테우스 모니터링 살펴보고 구성하기
[오픈소스컨설팅] 프로메테우스 모니터링 살펴보고 구성하기[오픈소스컨설팅] 프로메테우스 모니터링 살펴보고 구성하기
[오픈소스컨설팅] 프로메테우스 모니터링 살펴보고 구성하기Ji-Woong Choi
 
프로그래머에게 사랑받는 게임 기획서 작성법
프로그래머에게 사랑받는 게임 기획서 작성법프로그래머에게 사랑받는 게임 기획서 작성법
프로그래머에게 사랑받는 게임 기획서 작성법Lee Sangkyoon (Kay)
 
2022 01-okky-코드리뷰
2022 01-okky-코드리뷰2022 01-okky-코드리뷰
2022 01-okky-코드리뷰Myeongseok Baek
 
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018devCAT Studio, NEXON
 
[GPG스터디] 1.0 데이터 주도적 설계의 마법
[GPG스터디] 1.0 데이터 주도적 설계의 마법[GPG스터디] 1.0 데이터 주도적 설계의 마법
[GPG스터디] 1.0 데이터 주도적 설계의 마법Sehyeon Nam
 
목적에 맞게 Angular, React, Vue
목적에 맞게 Angular, React, Vue목적에 맞게 Angular, React, Vue
목적에 맞게 Angular, React, VueGunhee Lee
 

What's hot (20)

[140315 박민근] 젠킨스를 이용한 자동빌드 시스템 구축하기(ci)
[140315 박민근] 젠킨스를 이용한 자동빌드 시스템 구축하기(ci)[140315 박민근] 젠킨스를 이용한 자동빌드 시스템 구축하기(ci)
[140315 박민근] 젠킨스를 이용한 자동빌드 시스템 구축하기(ci)
 
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceKGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
 
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
윤석주, 신입 게임 프로그래머가 되는 법 - 넥슨 채용 프로세스 단계별 분석, NDC2019
 
[D2 오픈세미나]1.무한스크롤성능개선
[D2 오픈세미나]1.무한스크롤성능개선[D2 오픈세미나]1.무한스크롤성능개선
[D2 오픈세미나]1.무한스크롤성능개선
 
서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)
 
[AWSKRUG] 혼자서 커뮤니티 귀동냥하며 만든 Next.js & Amplify & serverless framework 서버리스 웹 플...
[AWSKRUG] 혼자서 커뮤니티 귀동냥하며 만든 Next.js & Amplify & serverless framework 서버리스 웹 플...[AWSKRUG] 혼자서 커뮤니티 귀동냥하며 만든 Next.js & Amplify & serverless framework 서버리스 웹 플...
[AWSKRUG] 혼자서 커뮤니티 귀동냥하며 만든 Next.js & Amplify & serverless framework 서버리스 웹 플...
 
웹을 지탱하는 기술
웹을 지탱하는 기술웹을 지탱하는 기술
웹을 지탱하는 기술
 
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
이승재, 실버바인 서버엔진 2 설계 리뷰, NDC2018
 
게임 서버 성능 분석하기
게임 서버 성능 분석하기게임 서버 성능 분석하기
게임 서버 성능 분석하기
 
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
[135] 우리 팀에서도 코드리뷰를 할 수 있을까 안오균
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
 
C# Game Server
C# Game ServerC# Game Server
C# Game Server
 
송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
 
파이썬 생존 안내서 (자막)
파이썬 생존 안내서 (자막)파이썬 생존 안내서 (자막)
파이썬 생존 안내서 (자막)
 
[오픈소스컨설팅] 프로메테우스 모니터링 살펴보고 구성하기
[오픈소스컨설팅] 프로메테우스 모니터링 살펴보고 구성하기[오픈소스컨설팅] 프로메테우스 모니터링 살펴보고 구성하기
[오픈소스컨설팅] 프로메테우스 모니터링 살펴보고 구성하기
 
프로그래머에게 사랑받는 게임 기획서 작성법
프로그래머에게 사랑받는 게임 기획서 작성법프로그래머에게 사랑받는 게임 기획서 작성법
프로그래머에게 사랑받는 게임 기획서 작성법
 
2022 01-okky-코드리뷰
2022 01-okky-코드리뷰2022 01-okky-코드리뷰
2022 01-okky-코드리뷰
 
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
홍성우, 게임 프로그래머는 어떻게 가르치나요?, NDC2018
 
[GPG스터디] 1.0 데이터 주도적 설계의 마법
[GPG스터디] 1.0 데이터 주도적 설계의 마법[GPG스터디] 1.0 데이터 주도적 설계의 마법
[GPG스터디] 1.0 데이터 주도적 설계의 마법
 
목적에 맞게 Angular, React, Vue
목적에 맞게 Angular, React, Vue목적에 맞게 Angular, React, Vue
목적에 맞게 Angular, React, Vue
 

Viewers also liked

비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기jeong seok yang
 
퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다jeong seok yang
 
퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다jeong seok yang
 
하코사세미나_캔버스 파이그래프 만들기
하코사세미나_캔버스 파이그래프 만들기하코사세미나_캔버스 파이그래프 만들기
하코사세미나_캔버스 파이그래프 만들기정석 양
 
JavaScript 2014 프론트엔드 기술 리뷰
JavaScript 2014 프론트엔드 기술 리뷰JavaScript 2014 프론트엔드 기술 리뷰
JavaScript 2014 프론트엔드 기술 리뷰Kenu, GwangNam Heo
 
나의 jQuery 실력 향상기
나의 jQuery 실력 향상기나의 jQuery 실력 향상기
나의 jQuery 실력 향상기정석 양
 
프론트엔드 개발자의 자바스크립트
프론트엔드 개발자의 자바스크립트 프론트엔드 개발자의 자바스크립트
프론트엔드 개발자의 자바스크립트 jeong seok yang
 
JavaSript Template Engine
JavaSript Template EngineJavaSript Template Engine
JavaSript Template EngineOhgyun Ahn
 
퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다정석 양
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web AnimationsChang W. Doh
 
웹 Front-End 실무 이야기
웹 Front-End 실무 이야기웹 Front-End 실무 이야기
웹 Front-End 실무 이야기JinKwon Lee
 
[토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강 [토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강 우영 주
 

Viewers also liked (13)

비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기
 
퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다
 
퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다
 
하코사세미나_캔버스 파이그래프 만들기
하코사세미나_캔버스 파이그래프 만들기하코사세미나_캔버스 파이그래프 만들기
하코사세미나_캔버스 파이그래프 만들기
 
JavaScript 2014 프론트엔드 기술 리뷰
JavaScript 2014 프론트엔드 기술 리뷰JavaScript 2014 프론트엔드 기술 리뷰
JavaScript 2014 프론트엔드 기술 리뷰
 
Jquery핵심노토
Jquery핵심노토Jquery핵심노토
Jquery핵심노토
 
나의 jQuery 실력 향상기
나의 jQuery 실력 향상기나의 jQuery 실력 향상기
나의 jQuery 실력 향상기
 
프론트엔드 개발자의 자바스크립트
프론트엔드 개발자의 자바스크립트 프론트엔드 개발자의 자바스크립트
프론트엔드 개발자의 자바스크립트
 
JavaSript Template Engine
JavaSript Template EngineJavaSript Template Engine
JavaSript Template Engine
 
퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations
 
웹 Front-End 실무 이야기
웹 Front-End 실무 이야기웹 Front-End 실무 이야기
웹 Front-End 실무 이야기
 
[토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강 [토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강
 

Similar to 컴포넌트 관점에서 개발하기

ABC: 다시 생각하는 컴포넌트
ABC: 다시 생각하는 컴포넌트ABC: 다시 생각하는 컴포넌트
ABC: 다시 생각하는 컴포넌트Chanhee Lee
 
Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Kyoung Up Jung
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
Java script 강의자료_ed13
Java script 강의자료_ed13Java script 강의자료_ed13
Java script 강의자료_ed13hungrok
 
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내Tae-Seong Park
 
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)SangIn Choung
 
ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는Taegon Kim
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Testbeom kyun choi
 
자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기Jeado Ko
 
개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)SangIn Choung
 
김윤환_포트폴리오
김윤환_포트폴리오김윤환_포트폴리오
김윤환_포트폴리오Yun-hwan Kim
 
Express framework tutorial
Express framework tutorialExpress framework tutorial
Express framework tutorial우림 류
 
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기Kenneth Ceyer
 
디자인 시스템 디자인하기
디자인 시스템 디자인하기디자인 시스템 디자인하기
디자인 시스템 디자인하기sangyong lee
 
[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱NAVER D2
 
워드프레스 For 플러그인
워드프레스 For 플러그인워드프레스 For 플러그인
워드프레스 For 플러그인082net
 
XECon2015 :: [2-3] 홍성범 - XE3 Theme 제작 소개
XECon2015 :: [2-3] 홍성범 - XE3 Theme 제작 소개XECon2015 :: [2-3] 홍성범 - XE3 Theme 제작 소개
XECon2015 :: [2-3] 홍성범 - XE3 Theme 제작 소개XpressEngine
 

Similar to 컴포넌트 관점에서 개발하기 (20)

ABC: 다시 생각하는 컴포넌트
ABC: 다시 생각하는 컴포넌트ABC: 다시 생각하는 컴포넌트
ABC: 다시 생각하는 컴포넌트
 
react-ko.pdf
react-ko.pdfreact-ko.pdf
react-ko.pdf
 
Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
Java script 강의자료_ed13
Java script 강의자료_ed13Java script 강의자료_ed13
Java script 강의자료_ed13
 
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
 
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
 
ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
 
자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기
 
개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)
 
김윤환_포트폴리오
김윤환_포트폴리오김윤환_포트폴리오
김윤환_포트폴리오
 
Express framework tutorial
Express framework tutorialExpress framework tutorial
Express framework tutorial
 
(스프링프레임워크 강좌)스프링부트개요 및 HelloWorld 따라하기
(스프링프레임워크 강좌)스프링부트개요 및 HelloWorld 따라하기(스프링프레임워크 강좌)스프링부트개요 및 HelloWorld 따라하기
(스프링프레임워크 강좌)스프링부트개요 및 HelloWorld 따라하기
 
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 
디자인 시스템 디자인하기
디자인 시스템 디자인하기디자인 시스템 디자인하기
디자인 시스템 디자인하기
 
[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱
 
워드프레스 For 플러그인
워드프레스 For 플러그인워드프레스 For 플러그인
워드프레스 For 플러그인
 
[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초
 
XECon2015 :: [2-3] 홍성범 - XE3 Theme 제작 소개
XECon2015 :: [2-3] 홍성범 - XE3 Theme 제작 소개XECon2015 :: [2-3] 홍성범 - XE3 Theme 제작 소개
XECon2015 :: [2-3] 홍성범 - XE3 Theme 제작 소개
 

More from 우영 주

스트리밍과 디지털 권리 관리
스트리밍과 디지털 권리 관리스트리밍과 디지털 권리 관리
스트리밍과 디지털 권리 관리우영 주
 
스트리밍과 플레이어
스트리밍과 플레이어스트리밍과 플레이어
스트리밍과 플레이어우영 주
 
프런트엔드개발, 지금과 다음
프런트엔드개발, 지금과 다음프런트엔드개발, 지금과 다음
프런트엔드개발, 지금과 다음우영 주
 
아재가 젊은이에게 사랑받는 마크업을 하는 방법
아재가 젊은이에게 사랑받는 마크업을 하는 방법아재가 젊은이에게 사랑받는 마크업을 하는 방법
아재가 젊은이에게 사랑받는 마크업을 하는 방법우영 주
 
Introduce Guetzli
Introduce GuetzliIntroduce Guetzli
Introduce Guetzli우영 주
 
스코프와 실행문맥
스코프와 실행문맥스코프와 실행문맥
스코프와 실행문맥우영 주
 
좋은 기능을 만드는 방법
좋은 기능을 만드는 방법좋은 기능을 만드는 방법
좋은 기능을 만드는 방법우영 주
 
서비스를 성공적으로 만드는 방법
서비스를 성공적으로 만드는 방법서비스를 성공적으로 만드는 방법
서비스를 성공적으로 만드는 방법우영 주
 
다함께, FluxUtils 한바퀴!
다함께, FluxUtils 한바퀴!다함께, FluxUtils 한바퀴!
다함께, FluxUtils 한바퀴!우영 주
 
BEM을 깨우치다.
BEM을 깨우치다.BEM을 깨우치다.
BEM을 깨우치다.우영 주
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises우영 주
 
명세부터 깨우치는 FILEAPI
명세부터 깨우치는 FILEAPI명세부터 깨우치는 FILEAPI
명세부터 깨우치는 FILEAPI우영 주
 
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기우영 주
 
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)우영 주
 
Javascript Test Double Sinon.js
Javascript Test Double Sinon.jsJavascript Test Double Sinon.js
Javascript Test Double Sinon.js우영 주
 
HTML5 BOILERPLATE를 소개합니다.
HTML5 BOILERPLATE를 소개합니다.HTML5 BOILERPLATE를 소개합니다.
HTML5 BOILERPLATE를 소개합니다.우영 주
 
이클립스로 GIT 사용하기
이클립스로 GIT 사용하기이클립스로 GIT 사용하기
이클립스로 GIT 사용하기우영 주
 

More from 우영 주 (18)

스트리밍과 디지털 권리 관리
스트리밍과 디지털 권리 관리스트리밍과 디지털 권리 관리
스트리밍과 디지털 권리 관리
 
스트리밍과 플레이어
스트리밍과 플레이어스트리밍과 플레이어
스트리밍과 플레이어
 
프런트엔드개발, 지금과 다음
프런트엔드개발, 지금과 다음프런트엔드개발, 지금과 다음
프런트엔드개발, 지금과 다음
 
아재가 젊은이에게 사랑받는 마크업을 하는 방법
아재가 젊은이에게 사랑받는 마크업을 하는 방법아재가 젊은이에게 사랑받는 마크업을 하는 방법
아재가 젊은이에게 사랑받는 마크업을 하는 방법
 
Introduce Guetzli
Introduce GuetzliIntroduce Guetzli
Introduce Guetzli
 
스코프와 실행문맥
스코프와 실행문맥스코프와 실행문맥
스코프와 실행문맥
 
좋은 기능을 만드는 방법
좋은 기능을 만드는 방법좋은 기능을 만드는 방법
좋은 기능을 만드는 방법
 
서비스를 성공적으로 만드는 방법
서비스를 성공적으로 만드는 방법서비스를 성공적으로 만드는 방법
서비스를 성공적으로 만드는 방법
 
다함께, FluxUtils 한바퀴!
다함께, FluxUtils 한바퀴!다함께, FluxUtils 한바퀴!
다함께, FluxUtils 한바퀴!
 
BEM을 깨우치다.
BEM을 깨우치다.BEM을 깨우치다.
BEM을 깨우치다.
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
명세부터 깨우치는 FILEAPI
명세부터 깨우치는 FILEAPI명세부터 깨우치는 FILEAPI
명세부터 깨우치는 FILEAPI
 
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
 
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
 
Javascript Test Double Sinon.js
Javascript Test Double Sinon.jsJavascript Test Double Sinon.js
Javascript Test Double Sinon.js
 
LESS와 EMMET
LESS와 EMMETLESS와 EMMET
LESS와 EMMET
 
HTML5 BOILERPLATE를 소개합니다.
HTML5 BOILERPLATE를 소개합니다.HTML5 BOILERPLATE를 소개합니다.
HTML5 BOILERPLATE를 소개합니다.
 
이클립스로 GIT 사용하기
이클립스로 GIT 사용하기이클립스로 GIT 사용하기
이클립스로 GIT 사용하기
 

컴포넌트 관점에서 개발하기

  • 1. 컴포넌트 관점에서 개발하기 2017 프론트엔드 트렌드&인사이트
  • 2. 주우영 프런트엔드 개발 시작하기 네이버는 이렇게 한다!, 위키북스 JavaScript Promise 한빛 eBook, 한빛미디어 페이스북 프론트엔드개발 그룹 운영 https://www.facebook.com/groups/webfrontend/ 레진엔터테인먼트 프론트엔드개발팀
  • 4. 현대 UI 개발에 있어 중요히 여기는 부분에 대해 이야기합니다.
  • 5. 현대 프레임워크의 공통된 접근법 컴포넌트 단위로 사고하고 디자인
  • 6. import {Component} from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Welcome to {{title}}</h1> `, styles: [` h1 { font-size: 4em; } `] }) export class AppComponent { title = 'app'; }
  • 7. import {Component} from 'react'; const style = { fontSize: '4em' }; class HelloMessage extends Component { static defaultProps = { title: 'React' }; render() { return ( <h1 style={style}> Welcome to {this.props.title} </h1> ); } }
  • 8. <style scoped> h1 { font-size: 4em; } </style> <template> <h1>Welcome to {{title}}</h1> </template> <script type="text/babel"> export default { data () { return { title: 'Vue' } } } </script>
  • 9. <dom-module id="hello-element"> <template> <style> h1 {font-size: 4em} </style> <h1>Welcome to {{title}}</h1> </template> <script> class HelloElement extends Polymer.Element { static get is() {return "hello-element";} constructor() { super(); this.title = "Polymer"; } } customElements.define(HelloElement.is, HelloElement); </script> </dom-module>
  • 11. 하나의 문제를 잘 해결하는 COMPONENT 프로그램
  • 12. 새로운 방법이 아닌 예로부터 모든 공학 분야의 공학자가 자주 사용해 오던 문제 해결 방법
  • 13. Unix Philosophy Write programs that do one thing and do it well. Write programs to work together. Doug Mcllroy, Unix pipeline inventor The UNIX Philosophy in 9 paramount precepts Mike Gancarz (a member of the team that designed the X Window System) Small is beautiful. Make each program do one thing well. Write programs handle text streams, because that is a universal interface.
  • 14. $ ps -ef Processes Status Report a snapshot of the current processes $ grep gradle Globally search a regular expression and print Searching plain-text data sets for lines that match a regular expression $ ps -ef | grep gradle
  • 15. 사고의 분산을 막고 하나의 문제에 집중함으로써 효율적으로 개발할 수 있다
  • 16. 설계의 오류를 쉽게 파악할 수 있고 상대적으로 테스트하기 쉽다
  • 17. 이식성을 높일 수 있고 변경에 유연하게 대체할 수 있다
  • 18. API UI는 자주적으로 동작하는 또 다른 프로그램, 그것을 API로 제어한다는 사고로 접근 자바스크립트를 개발할 때 우리는
  • 19. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); }
  • 20. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); } DOM을 직접 핸들링, 장황하고 UI의 형태를 한눈에 파악하기 힘듦
  • 21. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); } 상태를 class나 data attr에 설정 및 사용하여 전체적인 상태 흐름을 알기 힘듦
  • 22. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); } DOM API의 비용은 비쌈. 상태 변화를 위해 
 DOM API 호출이 남용됨
  • 23. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); } UI 상태 변화를 위한 render 외의 부가적 메서드 다량 정의
  • 24. 프리젠테이션 로직은 크고 복잡. 테스트하고 유지보수하기 괴롭다
  • 25. Functional Programming 컴포넌트 접근법은 함수형 프로그래밍하고도 관련이 깊다 부작용(Side effect)없이 하나의 일을 잘 수행하는 함수 그러한 함수를 조합 / 구성함으로써 큰 문제를 해결 F2 F3 F4 F5F1
  • 26. {
 “type”: “oval”,
 “size”: 32
 } Functional Programming and UI Component View = Function(state)
  • 27. function Header({title, desc}) { return ( <header className="header"> <div className="header__inner"> <h1 className="header__title">{title}</h1> <p className="header__description">{desc}</p> </div> </header> ); } View = Function(state) REMEMBER
  • 28. Header({ title: 'Hello World!', desc: 'This is Awesome.' }); <header class="..."> <div class="..."> <h1 class="...">Hello World!</h1> <p class="...">This is Awesome.</p> </div> </header>
  • 29. <header class="..."> <div class="..."> <h1 class="...">Hello World!</h1> <p class="...">This is Awesome</p> </div> </header> <header class="..."> <div class="..."> <h1 class="...">Welcome</h1> <p class="...">This is Awesome</p> </div> </header> Equal?
  • 30. <header class="..."> <div class="..."> <h1 class="...">Hello World!</h1> <p class="...">This is Awesome</p> </div> </header> <header class="..."> <div class="..."> <h1 class="...">Welcome</h1> <p class="...">This is Awesome</p> </div> </header> Equal?
  • 31. <header class="..."> <div class="..."> <h1 class="...">Hello World!</h1> <p class="...">This is Awesome</p> </div> </header> <header class="..."> <div class="..."> <h1 class="...">Welcome</h1> <p class="...">This is Awesome</p> </div> </header> Equal? FAIL
  • 33. HTML(TMPL), CSS, 자바스크립트를 분리하는게 당연한 관심사의 분리라고 생각 과거 우리는.
  • 34. Templates separate technologies, not concerns. 템플릿은 기술의 분리일 뿐 관심사의 분리가 아니다. Pete Hunt, React developer 페이트 헌트, 리액트 개발자 “ ”
  • 35.
  • 36.
  • 37. KingCard Component 중요한건 해결하고자 하는 문제 같은 문제를 해결한다면 관심사는 같다
  • 38. 이때, 분리된 환경 보다 한 곳에 있는 경우가 훨씬 수월하다 관심사가 같다면 수정 시, 함께 수정해야 할 확률이 높다
  • 39. HTML, CSS를 어떻게든 셋팅한 후 자바스크립트를 이어서 테스트 UI 테스트에 대한 자원 준비 없이 곧바로 컴포넌트를 테스트
  • 40. Test IconText Component it('iconDirection 속성에 left를 지정하면 아이콘이 좌측에 배치된다.', () => { // Given // When const wrapper = shallow( <IconText label="친구초대" icon="add-friend" iconDirection="left" /> ); // Then const children = wrapper.children('.icon-text__inner').children(); expect(children.first()).to.have.className('icon-text__icon'); expect(children.last()).to.have.className('icon-text__label'); });
  • 41. "## Header $ "## Header.js $ "## Header.test.js $ %## style.scss "## TallCard $ "## TallCard.js $ "## TallCard.test.js $ %## style.scss "## KingCard $ "## KingCard.js $ "## KingCard.test.js $ %## style.scss %## StickyBar "## StickyBar.js "## StickyBar.test.js %## style.scss 따라서 관련있는 것은 최대한 가까이에 두는 구조가 현재 유행
  • 42. const Button = (props) => ( <button className={'large' in props && 'large'}> {props.children} <style jsx>{` button { padding: 20px; background: #eee; color: #999 } .large { padding: 50px } `}</style> </button> ); 또는 하나의 파일 내 모든 관심사를 작성하는 방식도 선호
  • 43. 뭘 좀 만들어 봅시다. 이런 UI를 개발해 달라고 했을때 가장 먼저 한가지 일을 수행하는 최소 단위를 분석
  • 44. 뭘 좀 만들어 봅시다. 이런 UI를 개발해 달라고 했을때 가장 먼저 한가지 일을 수행하는 최소 단위를 분석
  • 45. 뭘 좀 만들어 봅시다. 이런 UI를 개발해 달라고 했을때 가장 먼저 한가지 일을 수행하는 최소 단위를 분석
  • 46. 뭘 좀 만들어 봅시다. 이런 UI를 개발해 달라고 했을때 가장 먼저 한가지 일을 수행하는 최소 단위를 분석 <TallCard/> 를 만들어 봅시다.
  • 47. BEM(Block, Element, Modifier) 컴포넌트와 어울리게 마크업하기 Block 애플리케이션의 구성 요소로서 독립된 존재 Element 블록을 구성하는 작은 단위 또는 자식 개체 Modifier 블록이나 요소의 테마, 동작을 표현
  • 49. <div class="tall-card tall-card_badge_up"> <div class="tall-card__badge"> <i class=“tall-card__badge-up"> <span class="blind">UP</span> </i> </div> <div class="tall-card__thumbnail"> <img class="tall-card__image" src="" alt=""/> </div> <div className="tall-card__information"> <h5 className="tall-card__title">레바툰</h5> <dl class="tall-card__meta"> <dt class=“tall-card__meta-key">장르</dt> <dd class=“tall-card__meta-value">개그 / 일상</dd> <dt class=“tall-card__meta-key">작가</dt> <dd class=“tall-card__meta-value">레바</dd> </dl> </div> </div> Markup with BEM
  • 50. const TallCard = ({title, image, badge, metadata = []}) => ( <div className={`tall-card ${badge === 'up' ? ‘tall-card_badge_up' … `}> <div className="tall-card__badge"> <i className=“tall-card__badge-up”/> </div> <div className="tall-card__thumbnail"> <img className="…" src={image} alt={`${title}의 썸네일`}/> </div> <div className="tall-card__information"> <h5 className="tall-card__title">{title}</h5> {metadata.length > 0 ? ( <dl className=“tall-card__meta"> ${metadata.map(({key, value}) => ([ <dt className=“tall-card__meta-key">{key}</dt>, <dt className=“tall-card__meta-key">{value}</dt> ]))} </dl> ) : null} </div> </div> ); Create React Component
  • 51. $module: 'icon-text'; .#{$module} { &__badge { /*...*/ &__up {/*...*/} } &__thumbnail { /*...*/ &__image {/*...*/} } &__information {/*...*/} &__title {/*...*/} &__meta {/*…*/} &__meta-key {/*...*/} &__mata-value {/*...*/} } Styling with SASS SASS의 interpolation은 컴포넌트 접근법과 잘 어울린다 스타일링 영역을 문법적으로 명확히 표현할 수 있다
  • 52. "## TallCard "## TallCard.js %## TallCard.scss "## TallCard "## TallCard.js "## TallCard.html %## TallCard.scss File structure 마크업 코드를 템플릿으로 분리한 경우 마크업을 자바스크립트에 포함한 경우
  • 53. Context Free <CardGroup/><SquareCard/> type = subscriptions 상위 컴포넌트 스타일이 하위 컴포넌트 스타일에 영향을 주면 안된다 컴포넌트는 어떤 문맥에서든 자유로워야 한다
  • 54. badge = up sensational = true 만약 특정 문맥에서 컴포넌트가 변화한다면 해당 컴포넌트에 Context Free <SquareCard/> badge = new 새로운 변환자(Modifier)를 추가한다
  • 55. Context Free <CardGroup/> CardList 컴포넌트는 badge가 up인 SquareCard 컴포넌트를 자식 컴포넌트로 포함하고 있을 뿐이다 type = subscriptions
  • 56. 타인의 잣대에 얽매이면 행복할 수 없듯 컴포넌트 역시 특정 문맥에 얽매이면 행복할 수 없다