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 Slide

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

    View Slide

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

    View Slide

  4. JavaScript

    View Slide

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

    View Slide

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

    View Slide

  7. Development/Debug

    View Slide

  8. 基本文法

    View Slide

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

    } else {
    message = 'ok!';

    }
    変数宣言

    View Slide

  10. 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 Slide

  11. 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 Slide

  12. 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 Slide

  13. // 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 Slide

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

    View Slide

  15. 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 Slide

  16. 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 Slide

  17. 非同期処理

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  22. 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 Slide

  23. 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 Slide

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

    View Slide

  25. 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 Slide

  26. DOM

    View Slide

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

    View Slide







  28. Click Me!



    View Slide

  29. // 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 Slide

  30. // 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 Slide

  31. TypeScript

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  35. 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 Slide

  36. 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 Slide

  37. 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 Slide

  38. 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 Slide

  39. Gradual Typing

    View Slide

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

    View Slide

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

    View Slide

  42. Structural Subtyping

    View Slide

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

    View Slide

  44. 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 Slide

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

    View Slide

  46. React

    View Slide

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

    View Slide

  48. View Slide

  49. 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 Slide

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

    {this.props.label}

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

    View Slide

  51. View Slide

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

  53. 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 Slide

  54. 設計パターン

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  59. 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 Slide

  60. Container Component
    Stateless Component

    View Slide

  61. 1. イベント発生

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  65. Lifecycle

    View Slide

  66. Component Lifecycle

    View Slide

  67. 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 Slide

  68. Practice

    View Slide

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

    View Slide

  70. 環境構築
    $ npm install -g create-react-app
    $ create-react-app booklist-front \
    [email protected]/create-react-app-ts-dev
    $ cd booklist-front
    $ yarn start

    View Slide