Slide 1

Slide 1 text

JavaScript クックパッド サマーインターンシップ 10 Day Tech for service engineers

Slide 2

Slide 2 text

Agenda 1. JavaScript 2. TypeScript 3. React

Slide 3

Slide 3 text

https://code.visualstudio.com/

Slide 4

Slide 4 text

JavaScript

Slide 5

Slide 5 text

JavaScript •ブラウザで動作するプログラミング言語 •HTMLを動的に変更してインタラクティブなWebサイト を構築するために使われる •最近はNode.jsやReactNativeなどブラウザ以外でも動 作する環境も多くある

Slide 6

Slide 6 text

https://developer.mozilla.org/ja/

Slide 7

Slide 7 text

Development/Debug

Slide 8

Slide 8 text

基本文法

Slide 9

Slide 9 text

// جຊతʹ͸constΛ࢖͏ const str = 'x'; const arr = [1, 2, 3]; // ఆٛޙʹ࠶୅ೖ͕ඞཁͳ৔߹͸letΛ࢖͏ let message; if (err) { message = 'error!';
 } else { message = 'ok!';
 } 変数宣言

Slide 10

Slide 10 text

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; リテラル

Slide 11

Slide 11 text

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] 配列

Slide 12

Slide 12 text

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 } オブジェクト

Slide 13

Slide 13 text

// 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 関数

Slide 14

Slide 14 text

class Greeter { constructor(name) { this.name = name; } greet() { return `Hello ${this.name}!`; } } const g = new Greeter('hokaccha'); g.greet(); //=> 'Hello hokaccha!'; Class

Slide 15

Slide 15 text

Modules // lib/Greeter.js export default class Greeter { constructor(name) { this.name = name; } greet() { return `Hello ${name}!`; } } export function hello(name) { return `Hello ${name}!`; }

Slide 16

Slide 16 text

Modules // app.js // default import import Greeter from './lib/Greeter'; // named import import { hello } from './lib/Greeter'; // mixed import Greeter, { hello } from './lib/Greeter';

Slide 17

Slide 17 text

非同期処理

Slide 18

Slide 18 text

同期 // Ծʹwait͕ॲཧΛϒϩοΫͨ͠ͱ͢Δͱ଴͍ͬͯΔؒʹԿ΋Ͱ͖ͳ͍ wait(1000); doSomething(); 非同期 // ଴͕ͪ࣌ؒܦաͨ͠Β࣮ߦ͞ΕΔؔ਺Λొ࿥ wait(1000, () => { doSomething(); }); // ܧଓͯ͠ॲཧΛଓ͚ΒΕΔ

Slide 19

Slide 19 text

非同期処理の実装 •callback •Promise •async/await

Slide 20

Slide 20 text

callback http.get('/a', response => { // ... });

Slide 21

Slide 21 text

callback http.get('/a', responseA => { http.get('/b', responseB => { http.get('/c', responseC => { // ... }); }); });

Slide 22

Slide 22 text

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); } // ... }); }); });

Slide 23

Slide 23 text

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 });

Slide 24

Slide 24 text

Promise get('/a') .then(responseA => { return get('/b'); }) .then(responseB => { return get('/c'); }) .then(responseC => { // do something }) .catch(err => { // error handling });

Slide 25

Slide 25 text

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 } }

Slide 26

Slide 26 text

DOM

Slide 27

Slide 27 text

DOM •HTML文書をプログラムから扱うためのAPI仕様 •JavaScriptの言語仕様とは別に仕様が策定されている

Slide 28

Slide 28 text

Click Me!

Slide 29

Slide 29 text

// 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; });

Slide 30

Slide 30 text

// 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*

Slide 31

Slide 31 text

TypeScript

Slide 32

Slide 32 text

TypeScript •Microsoftによって開発されているプログラミング言語 •JavaScriptに静的型付けの機能を取り入れたAltJS •JavaScriptのスーパーセット

Slide 33

Slide 33 text

JavaScript function greeter(person) { return "Hello, " + person; } const user = "hokaccha"; const message = greeter(user);

Slide 34

Slide 34 text

TypeScript function greeter(person: string): string { return "Hello, " + person; } const user = "hokaccha"; const message = greeter(user);

Slide 35

Slide 35 text

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'.

Slide 36

Slide 36 text

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;

Slide 37

Slide 37 text

Generics class Queue { private data: T[] = []; enqueue(item: T) { return this.data.push(item); } dequeue(): T { return this.data.shift(); } } const queue = new Queue(); queue.enqueue(10); queue.enqueue('x'); // Error!

Slide 38

Slide 38 text

Generics interface User { name: string; } async function getUser(): Promise { const response = await fetch('/user'); const body = await response.json(); return body; } async function f() { const user: User = await getUser(); }

Slide 39

Slide 39 text

Gradual Typing

Slide 40

Slide 40 text

Gradual Typing •静的片付けを部分的に導入することができる型システム •TypeScriptでは型検査をしないany型により実現される

Slide 41

Slide 41 text

// Ҿ਺ͷܕ͕anyʹͳΔͷͰͲΜͳܕͰ΋௨Δ function greeter(person) { return "Hello, " + person; } const user = [1, 2, 3]; const message = greeter(user); //=> ok Gradual Typing

Slide 42

Slide 42 text

Structural Subtyping

Slide 43

Slide 43 text

•部分型かどうかを構造が同じかどうかで判定する •静的型におけるダックタイピング Structural Subtyping

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

class User { name: string; } class Product { name: string; } const user: User = new Product(); // ok const product: Product = new User(); // ok Structural Subtyping

Slide 46

Slide 46 text

React

Slide 47

Slide 47 text

JavaScript Frameworks •jQuery •Backbone.js •Angular •Vue.js •React

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

class App extends React.Component { constructor(props) { super(props); this.state = { name: '' }; } handleInput(event) { this.setState({ name: event.target.value }); } render() { return
this.handleInput(event)} />
Hello, {this.state.name}
; } } ReactDOM.render(, document.getElementById('app'));

Slide 50

Slide 50 text

class Button extends React.Component { render() { return this.props.onClick()}> {this.props.label} } } alert('Hi!')} /> JSX

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

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
  • {user.name}
  • ; }); return
    {items}
    ; } }

    Slide 53

    Slide 53 text

    interface State { name: string; } interface Props { defaultName: string; } class App extends React.Component { constructor(props: Props) { super(props); this.state = { name: props.defaultName }; } handleClick() { this.setState({ a: 'b' }); // Error } } ; // Error With TypeScript

    Slide 54

    Slide 54 text

    設計パターン

    Slide 55

    Slide 55 text

    stateとprops •state: コンポーネント自身が管理している状態 •props: 親コンポーネントから受け取る不変なパラメータ

    Slide 56

    Slide 56 text

    Presentational Component •データを元にどういうviewを構築するかだけに専念する •状態を持たないStatelessなコンポーネントとして作る •親コンポーネントからもらうpropsのみに依存する

    Slide 57

    Slide 57 text

    class Greeter extends React.Component<{}, {}> { render() { return
    Hello, {this.props.name}
    ; } } // ୯ͳΔؔ਺ͱͯ͠΋ఆٛͰ͖Δ function Greeter(props) { return
    Hello, {this.props.name}
    ; } Stateless Component

    Slide 58

    Slide 58 text

    Container Component •ツリーのルートでstateを持つコンポーネント •子のコンポーネントに状態を渡してツリーを構築する •イベントをハンドリングしてstateの更新をおこなう

    Slide 59

    Slide 59 text

    class App extends React.Component { constructor(props) { super(props); this.state = { name: '' }; } handleInput(event) { this.setState({ name: event.target.value }); } render() { return
    this.handleInput(event)} />
    ; } } Container Component

    Slide 60

    Slide 60 text

    Container Component Stateless Component

    Slide 61

    Slide 61 text

    1. イベント発生

    Slide 62

    Slide 62 text

    1. イベント発生 2. 更新通知

    Slide 63

    Slide 63 text

    1. イベント発生 2. 更新通知 3. state更新

    Slide 64

    Slide 64 text

    1. イベント発生 2. 更新通知 3. state更新 4. DOM更新

    Slide 65

    Slide 65 text

    Lifecycle

    Slide 66

    Slide 66 text

    Component Lifecycle

    Slide 67

    Slide 67 text

    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() { // ... } }

    Slide 68

    Slide 68 text

    Practice

    Slide 69

    Slide 69 text

    1. Rubyのサーバーから書籍のリストを取得して表示 2. タイトルでインクリメンタルサーチする機能を実装 3. 各フィールドでソートできる機能を実装 4. スタイルをいい感じにする

    Slide 70

    Slide 70 text

    環境構築 $ npm install -g create-react-app $ create-react-app booklist-front \ --scripts-version=@hokaccha/create-react-app-ts-dev $ cd booklist-front $ yarn start