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
Kazuhito Hokamura
September 18, 2018
Technology
0
9.4k
cookpad summer internship 2018 - JavaScript
Kazuhito Hokamura
September 18, 2018
Tweet
Share
More Decks by Kazuhito Hokamura
See All by Kazuhito Hokamura
TypeScriptとGraphQLで実現する 型安全なAPI実装 / TSKaigi 2024
hokaccha
5
4.6k
Kotlin製のGraphQLサーバーをNode.jsでモジュラモノリス化している話
hokaccha
0
3.5k
GraphQLの負債と向き合うためにやっていること
hokaccha
2
1.5k
ユビーのアーキテクチャに対する取り組み
hokaccha
1
430
RailsエンジニアのためのNext.js入門
hokaccha
7
20k
Cookpad Summer Internship 2021 Web Frontend
hokaccha
0
7.2k
巨大なモノリシック Rails アプリケーションの マイクロサービス化戦略 / 2019 microservices in cookpad
hokaccha
3
3.9k
巨大なRailsアプリケーションを「普通」にするための取り組み
hokaccha
1
1k
Web Frontend Improvement in Cookpad
hokaccha
1
1.1k
Other Decks in Technology
See All in Technology
金融サービスにおける高速な価値提供とAIの役割 #BetAIDay
layerx
PRO
0
180
恐怖!テストコードなき夜
tsukuboshi
2
110
Wasmで社内ツールを作って配布しよう
askua
0
160
経験がないことを言い訳にしない、 AI時代の他領域への染み出し方
parayama0625
0
280
株式会社島津製作所_研究開発(集団協業と知的生産)の現場を支える、OSS知識基盤システムの導入
akahane92
1
1.3k
地域コミュニティへの「感謝」と「恩返し」 / 20250726jawsug-tochigi
kasacchiful
0
110
Mambaで物体検出 完全に理解した
shirarei24
2
150
クマ×共生 HACKATHON - 熊対策を『特別な行動」から「生活の一部」に -
pharaohkj
0
260
[TechNight #91] Oracle Database 最新パフォーマンス分析手法
oracle4engineer
PRO
4
300
AI によるドキュメント処理を加速するためのOCR 結果の永続化と再利用戦略
tomoaki25
0
240
AIエージェントを支える設計
tkikuchi1002
12
2.6k
経理出身PdMがAIプロダクト開発を_ハンズオンで学んだ話.pdf
shunsukenarita
1
260
Featured
See All Featured
KATA
mclloyd
31
14k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
Statistics for Hackers
jakevdp
799
220k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
110
19k
Testing 201, or: Great Expectations
jmmastey
43
7.6k
What's in a price? How to price your products and services
michaelherold
246
12k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.8k
A Modern Web Designer's Workflow
chriscoyier
695
190k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
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