Upgrade to Pro — share decks privately, control downloads, hide ads and more …

cookpad summer internship 2018 - JavaScript

cookpad summer internship 2018 - JavaScript

Kazuhito Hokamura

September 18, 2018
Tweet

More Decks by Kazuhito Hokamura

Other Decks in Technology

Transcript

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

    View full-size slide

  2. Agenda
    1. JavaScript
    2. TypeScript
    3. React

    View full-size slide

  3. https://code.visualstudio.com/

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  6. Development/Debug

    View full-size slide

  7. 基本文法

    View full-size slide

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

    } else {
    message = 'ok!';

    }
    変数宣言

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  16. 非同期処理

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  32. 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;

    View full-size slide

  33. 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!

    View full-size slide

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

    View full-size slide

  35. Gradual Typing

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  38. Structural Subtyping

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  43. 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'));

    View full-size slide

  44. class Button extends React.Component {
    render() {
    return this.props.onClick()}>

    {this.props.label}

    }
    }
    alert('Hi!')} />
    JSX

    View full-size slide

  45. 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};
    }
    }

    View full-size slide

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

    View full-size slide

  47. 設計パターン

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  53. Container Component
    Stateless Component

    View full-size slide

  54. 1. イベント発生

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  58. Component Lifecycle

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide