Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
cookpad summer internship 2018 - JavaScript
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Kazuhito Hokamura
September 18, 2018
Technology
9.5k
0
Share
cookpad summer internship 2018 - JavaScript
Kazuhito Hokamura
September 18, 2018
More Decks by Kazuhito Hokamura
See All by Kazuhito Hokamura
TypeScriptとGraphQLで実現する 型安全なAPI実装 / TSKaigi 2024
hokaccha
5
5k
Kotlin製のGraphQLサーバーをNode.jsでモジュラモノリス化している話
hokaccha
0
3.8k
GraphQLの負債と向き合うためにやっていること
hokaccha
2
1.6k
ユビーのアーキテクチャに対する取り組み
hokaccha
1
470
RailsエンジニアのためのNext.js入門
hokaccha
7
22k
Cookpad Summer Internship 2021 Web Frontend
hokaccha
0
7.3k
巨大なモノリシック Rails アプリケーションの マイクロサービス化戦略 / 2019 microservices in cookpad
hokaccha
3
4.1k
巨大なRailsアプリケーションを「普通」にするための取り組み
hokaccha
1
1.1k
Web Frontend Improvement in Cookpad
hokaccha
1
1.2k
Other Decks in Technology
See All in Technology
TanStack Start エコシステムの現在地 / TanStack Start Ecosystem 2026
iktakahiro
1
350
Data Intelligence Engineering Unit 部門と各ポジション紹介
sansantech
PRO
0
130
プロダクトを育てるように生成AIによる開発プロセスを育てよう
kakehashi
PRO
1
840
会社紹介資料 / Sansan Company Profile
sansan33
PRO
16
410k
プロダクトを触って語って理解する、チーム横断バグバッシュのすすめ / 20260411 Naoki Takahashi
shift_evolve
PRO
1
200
Tour of Agent Protocols: MCP, A2A, AG-UI, A2UI with ADK
meteatamel
1
210
OCI技術資料 : 証明書サービス概要
ocise
1
7.2k
推し活エージェント
yuntan_t
1
870
Network Firewall Proxyで 自前プロキシを消し去ることができるのか
gusandayo
0
210
New CBs New Challenges
ysuzuki
1
150
I ran an automated simulation of fake news spread using OpenClaw.
zzzzico
1
980
Autonomous Database - Dedicated 技術詳細 / adb-d_technical_detail_jp
oracle4engineer
PRO
5
13k
Featured
See All Featured
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
270
Everyday Curiosity
cassininazir
0
190
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
300
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
670
Measuring & Analyzing Core Web Vitals
bluesmoon
9
800
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
1
500
Chasing Engaging Ingredients in Design
codingconduct
0
160
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
250
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
880
Facilitating Awesome Meetings
lara
57
6.8k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Transcript
JavaScript クックパッド サマーインターンシップ 10 Day Tech for service engineers
Agenda 1. JavaScript 2. TypeScript 3. React
https://code.visualstudio.com/
JavaScript
JavaScript •ブラウザで動作するプログラミング言語 •HTMLを動的に変更してインタラクティブなWebサイト を構築するために使われる •最近はNode.jsやReactNativeなどブラウザ以外でも動 作する環境も多くある
https://developer.mozilla.org/ja/
Development/Debug
基本文法
// جຊతʹconstΛ͏ const str = 'x'; const arr = [1,
2, 3]; // ఆٛޙʹ࠶ೖ͕ඞཁͳ߹letΛ͏ let message; if (err) { message = 'error!'; } else { message = 'ok!'; } 変数宣言
const num1 = 100; const num2 = 3.141592; const str1
= 'xxx'; const str2 = "yyy"; const str3 = `foo${str}bar`; const x = null; const bool = true; const re = /foo.+$/i; リテラル
const arr = [1, 2, 3]; arr[0] //=> 1 //
for-ofͰΠςϨʔγϣϯ for (const v of arr) { console.log(v); // 1, 2, 3 } // ֤छϝιουͰΠςϨʔγϣϯ arr.forEach((v) => { console.log(v); }) //=> 1, 2, 3 arr.map((v) => { return v * 2; }); //=> [2, 4, 6] arr.filter((v) => { return v > 1; }); //=> [2, 3] 配列
const obj = { foo: 'bar', fn: () => {
console.log('hello!') } }; obj.foo; //=> 'bar' obj.fn(); //=> hello! obj.a = 'b'; // Shorthand property names const x = 1; const y = 2; const obj2 = { x, y }; // { x: x, y: y } オブジェクト
// function จ function square(x) { return x * x;
} // function ࣜ const square = function(x) { return x * x; }; // Arrow function ࣜ const square = (x) => { return x * x; }; // Ҿ͕1ͭͷͱ͖ () ΛলུՄೳɻ{ } Λলུͨ͠߹୯Ұͷ͕ࣜॻ͚ͯͦͷࣜͷ͕return͞ΕΔ const square = x => x * x; square(5); //=> 25 関数
class Greeter { constructor(name) { this.name = name; } greet()
{ return `Hello ${this.name}!`; } } const g = new Greeter('hokaccha'); g.greet(); //=> 'Hello hokaccha!'; Class
Modules // lib/Greeter.js export default class Greeter { constructor(name) {
this.name = name; } greet() { return `Hello ${name}!`; } } export function hello(name) { return `Hello ${name}!`; }
Modules // app.js // default import import Greeter from './lib/Greeter';
// named import import { hello } from './lib/Greeter'; // mixed import Greeter, { hello } from './lib/Greeter';
非同期処理
同期 // Ծʹwait͕ॲཧΛϒϩοΫͨ͠ͱ͢Δͱ͍ͬͯΔؒʹԿͰ͖ͳ͍ wait(1000); doSomething(); 非同期 // ͕ͪ࣌ؒܦաͨ͠Β࣮ߦ͞ΕΔؔΛొ wait(1000, ()
=> { doSomething(); }); // ܧଓͯ͠ॲཧΛଓ͚ΒΕΔ
非同期処理の実装 •callback •Promise •async/await
callback http.get('/a', response => { // ... });
callback http.get('/a', responseA => { http.get('/b', responseB => { http.get('/c',
responseC => { // ... }); }); });
callback http.get('/a', (err, responseA) => { if (err) { return
handleError(err); } http.get('/b', (err, responseB) => { if (err) { return handleError(err); } http.get('/c', (err, responseC) => { if (err) { return handleError(err); } // ... }); }); });
Promise function get(url) { return new Promise((resolve, reject) => {
http.get(url, (err, response) => { if (err) { reject(err); } else { resolve(response); } }); }); } get('/a').then(response => { // do something }).catch(err => { // error handling });
Promise get('/a') .then(responseA => { return get('/b'); }) .then(responseB =>
{ return get('/c'); }) .then(responseC => { // do something }) .catch(err => { // error handling });
async/await async function req() { const responseA = await get('/a');
const responseB = await get('/b'); const responseC = await get('/c'); return responseC; } async function f() { try { const res = await req(); // do something } catch (err) { // error handling } }
DOM
DOM •HTML文書をプログラムから扱うためのAPI仕様 •JavaScriptの言語仕様とは別に仕様が策定されている
<!DOCTYPE html> <html> <head> <script src="app.js" defer></script> </head> <body> <button
id="button">Click Me!</button> <div id="message"></div> </body> </html>
// HTMLʹॻ͔Ε͍ͯΔ button ཁૉΛऔಘ const button = document.getElementById('button'); // click͞Εͨͱ͖ͷϋϯυϥʔΛొ
button.addEventListener('click', async () => { // HTTP RequestͰAPIΛݺͼग़͢ const response = await fetch('/message'); const body = await response.json(); // #messageͷ༰Λॻ͖͑Δ document.getElementById('message').innerHTML = body.message; });
// HTMLʹॻ͔Ε͍ͯΔ button ཁૉΛऔಘ const button = document.getElementById('button'); // click͞Εͨͱ͖ͷϋϯυϥʔΛొ
button.addEventListener('click', async () => { // HTTP RequestͰAPIΛݺͼग़͢ const response = await fetch('/message'); const body = await response.json(); // #messageͷ༰Λॻ͖͑Δ document.getElementById('message').innerHTML = body.message; }); %0."1*
TypeScript
TypeScript •Microsoftによって開発されているプログラミング言語 •JavaScriptに静的型付けの機能を取り入れたAltJS •JavaScriptのスーパーセット
JavaScript function greeter(person) { return "Hello, " + person; }
const user = "hokaccha"; const message = greeter(user);
TypeScript function greeter(person: string): string { return "Hello, " +
person; } const user = "hokaccha"; const message = greeter(user);
TypeScript function greeter(person: string): string { return "Hello, " +
person; } const user = [1, 2, 3]; const message = greeter(user); //=> error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.
Basic Types let str: string; let num: number; let bool:
boolean; let arr: string[]; let fn: (a: string, b: string) => boolean; type StrOrArr = string | string[]; type StrOrNull = string | null;
Generics class Queue<T> { private data: T[] = []; enqueue(item:
T) { return this.data.push(item); } dequeue(): T { return this.data.shift(); } } const queue = new Queue<number>(); queue.enqueue(10); queue.enqueue('x'); // Error!
Generics interface User { name: string; } async function getUser():
Promise<User> { const response = await fetch('/user'); const body = await response.json(); return body; } async function f() { const user: User = await getUser(); }
Gradual Typing
Gradual Typing •静的片付けを部分的に導入することができる型システム •TypeScriptでは型検査をしないany型により実現される
// Ҿͷܕ͕anyʹͳΔͷͰͲΜͳܕͰ௨Δ function greeter(person) { return "Hello, " + person;
} const user = [1, 2, 3]; const message = greeter(user); //=> ok Gradual Typing
Structural Subtyping
•部分型かどうかを構造が同じかどうかで判定する •静的型におけるダックタイピング Structural Subtyping
interface Person { firstName: string; lastName: string; } class User
{ firstName: string; lastName: string; } const user1: Person = new User(); // ok const user2: Person = { firstName: "Kazuhito", lastName: "Hokamura" }; // ok Structural Subtyping
class User { name: string; } class Product { name:
string; } const user: User = new Product(); // ok const product: Product = new User(); // ok Structural Subtyping
React
JavaScript Frameworks •jQuery •Backbone.js •Angular •Vue.js •React
None
class App extends React.Component { constructor(props) { super(props); this.state =
{ name: '' }; } handleInput(event) { this.setState({ name: event.target.value }); } render() { return <div> <input type="text" onInput={event => this.handleInput(event)} /> <div>Hello, {this.state.name}</div> </div>; } } ReactDOM.render(<App />, document.getElementById('app'));
class Button extends React.Component { render() { return <button onClick={()
=> this.props.onClick()}> <i className={`icon-${this.props.icon}`} /> {this.props.label} </button> } } <Button label="Click Me" icon="caret" onClick={() => alert('Hi!')} /> JSX
None
Lists and Keys class App extends React.Component { render() {
// users: [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }] const items = this.props.users.map(user => { return <li key={user.id}>{user.name}</li>; }); return <div>{items}</div>; } }
interface State { name: string; } interface Props { defaultName:
string; } class App extends React.Component<Props, State> { constructor(props: Props) { super(props); this.state = { name: props.defaultName }; } handleClick() { this.setState({ a: 'b' }); // Error } } <App foo="bar" />; // Error With TypeScript
設計パターン
stateとprops •state: コンポーネント自身が管理している状態 •props: 親コンポーネントから受け取る不変なパラメータ
Presentational Component •データを元にどういうviewを構築するかだけに専念する •状態を持たないStatelessなコンポーネントとして作る •親コンポーネントからもらうpropsのみに依存する
class Greeter extends React.Component<{}, {}> { render() { return <div
className="greeter">Hello, {this.props.name}</div>; } } // ୯ͳΔؔͱͯ͠ఆٛͰ͖Δ function Greeter(props) { return <div className="greeter">Hello, {this.props.name}</div>; } Stateless Component
Container Component •ツリーのルートでstateを持つコンポーネント •子のコンポーネントに状態を渡してツリーを構築する •イベントをハンドリングしてstateの更新をおこなう
class App extends React.Component { constructor(props) { super(props); this.state =
{ name: '' }; } handleInput(event) { this.setState({ name: event.target.value }); } render() { return <div> <input type="text" onInput={event => this.handleInput(event)} /> <Greeter name={this.state.name} /> </div>; } } Container Component
Container Component Stateless Component
1. イベント発生
1. イベント発生 2. 更新通知
1. イベント発生 2. 更新通知 3. state更新
1. イベント発生 2. 更新通知 3. state更新 4. DOM更新
Lifecycle
Component Lifecycle
Fetch data class App extends React.Component { constructor(props) { super(props);
this.state = { name: '' }; } async componentDidMount() { const response = await fetch('/user'); const body = await response.json(); this.setState({ name: body.name }); } render() { // ... } }
Practice
1. Rubyのサーバーから書籍のリストを取得して表示 2. タイトルでインクリメンタルサーチする機能を実装 3. 各フィールドでソートできる機能を実装 4. スタイルをいい感じにする
環境構築 $ npm install -g create-react-app $ create-react-app booklist-front \
--scripts-version=@hokaccha/create-react-app-ts-dev $ cd booklist-front $ yarn start