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

The state of React.js 2016

The state of React.js 2016

A slide for html5j #65
http://eventdots.jp/event/589181

2016/07/27: Updated about React.PureComponent

koba04

May 30, 2016
Tweet

More Decks by koba04

Other Decks in Programming

Transcript

  1. 5IFTUBUFPG3FBDUKT
    IUNMKWPM

    !LPCB

    View full-size slide

  2. w XJMMCFIFMEJO+VOF
    "3FBDUKTNFFUVQPSHBOJ[FS

    View full-size slide

  3. 3FBDU&VSPQFJO1BSJT✈

    View full-size slide

  4. 8IPVTFT3FBDUKT

    View full-size slide

  5. 'BDFCPPL
    http://facebook.github.io/react/blog/2015/03/10/react-v0.13.html

    View full-size slide

  6. 5XJUUFS NPCJMF

    View full-size slide

  7. 3FBDUKTJTBCBUUMFUFTUFEMJCSBSZ
    GBDFCPPLVTFT3FBDUPONBTUFSCSBODIBUGBDFCPPLDPN

    View full-size slide

  8. 5IFIJTUPSZPG3FBDUKT

    View full-size slide

  9. 2013 2014 2015 2016
    Flux
    v0.13
    ReactNative
    for iOS
    GraphQL
    Redux Relay
    React Native
    for Android
    v0.14
    React Native
    for Windows
    v15.0.0

    View full-size slide

  10. w *UIJOLUIFSFBTPONBOZQFPQMFVTF3FBDUJT/05B
    QFSGPSNBODF
    w 'PSQSFEJDUBCMF6*NBOBHFNFOUCZl%FDMBSBUJWFBOEQVSF
    $PNQPOFOUzBOEl&YQMJDJUEBUBqPXzXJUIMFTT
    QFSGPSNBODFEFHSBEBUJPO
    w 1SPWJEJOHFTDBQFIBUDIFT
    8IZ3FBDU

    View full-size slide

  11. w :PVDBODSFBUFNPTUDPNQPOFOUTBT4UBUFMFTT'VODUJPO
    $PNQPOFOUT 4'$

    w 4'$EPFTO`UIBTBCBDLJOHJOTUBODF
    w /PTUBUF /PMJGFDZDMFNFUIPET /PSFGT
    w 1FSGPQUJNJTBUJPOTGPS4'$XJMMCFJOUIFGVUVSF
    4UBUFMFTT'VODUJPO$PNQPOFOUT
    const Item = ({item}) => (

    {item.name}×{item.count}

    );
    //

    View full-size slide

  12. %PZPVOFFETUBUFTPSMJGFDZDMF
    NFUIPETJOZPVSDPNQPOFOUT
    ↪︎&4$MBTTFT$PNQPOFOUT

    View full-size slide

  13. &4$MBTTFT
    class Counter extends React.Component {
    constructor(…args) {

    super(…args);
    this.state = {
    count: 0
    };
    this.onClick = this.onClick.bind(this);
    }
    onClick() {
    this.setState({
    count: this.state.count + 1
    });
    }
    render() {
    return (

    ++
    {this.state.count}

    );
    }

    View full-size slide

  14. w 4VQQPSUJOHNJOJNVN"1*T
    w *UEPFTO`UTVQQPSUSFQMBDF4UBUF JT.PVOUFE
    w .JYJOTBSFEFBE -POHMJWF)JHI0SEFS$PNQPOFOUT )0$

    &4$MBTTFT$PNQPOFUT
    import shallowCompare from ‘react-addons-shallow-compare’;
    const pure = Component => class PureComponent extends React.Component {
    shouldComponentUpdate(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
    }
    render () {
    return
    }
    };
    const Item = ({item}) => {item.name}×{item.count};
    const PureItem = pure(Item);

    View full-size slide

  15. w 3FBDUDSFBUF$MBTTGFFMTPVUEBUFE
    w *UIBTGFBUVSFTUIBUJTDPOWFOJFOUGPSEFWFMPQFST
    w NJYJOH‎)JHI0SEFS$PNQPOFOUT
    w BVUPCJOEJOH‎&4$MBTT'JFMET4UBUJD1SPQFSUJFT
    w *UNBZCFDPNFBTFQBSBUFQBDLBHF
    3FBDUDSFBUF$MBTT
    class Button extends React.Component {
    onClick = () => this.setState({count: this.state.count + 1});
    }
    Stage1

    View full-size slide

  16. DPSFOPUFT.BZ

    View full-size slide

  17. w "TJNQMFCFODINBSLGPS&4$MBTTFT XJUI
    TIPVME$PNQPOFOU6QEBUF
    WT4'$
    w IUUQTKTpEEMFOFULPCBKNL
    &4$MBTTFTWT4'$

    View full-size slide

  18. "EE3FBDU1VSF$PNQPOFOU JOIFSJUQVSJUZGPS
    GVODUJPOBMDPNQPOFOUT
    WIP
    PureComponent was merged as #7195.

    It’s a PureRenderMixin for ES Classes.

    View full-size slide

  19. "EE3FBDU1VSF$PNQPOFOU JOIFSJUQVSJUZGPS
    GVODUJPOBMDPNQPOFOUT
    class Post extends React.PureComponent { // or React.Component
    render() {
    return (




    );
    }
    }
    function PostHeader(props) {
    // ...
    }
    function PostBody(props) {
    // ...
    }
    Pure
    Pure
    This wasn’t merged

    View full-size slide

  20. "QJUGBMMPGTIPVME$PNQPOFOU6QEBUF
    import shallowCompare from ‘react-addons-shallow-compare’;
    class Item extends React.Component {
    shouldComponentUpdate(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
    }
    render() {
    return (

    {this.props.name}
    click

    );
    }
    }
    console.log(‘click’)} />

    View full-size slide

  21. SFBDUBEEPOTQFSG
    w 1FSGIBTSFXSJUUFOCZ%BO"CSBNPWBUW
    w QSJOU%0.SFOBNFEUPQSJOU0QFSBUJPOT
    w :PVDBO
    import Perf from ‘react-addons-perf’;
    Perf.start();
    ReactDOM.render(, el);
    setTimeout(() => {
    ReactDOM.render(, el);
    Perf.stop();
    Perf.printWasted();
    }, 1000);

    View full-size slide

  22. XIZEJEZPVVQEBUF
    w IUUQTHJUIVCDPNHBSCMFTXIZEJEZPVVQEBUF
    w zJGEFpOFB$PNQPOFOUIBTDPNQPOFOU%JE6QEBUF UIF
    XIZEJEZPVVQEBUFXJMMOPUXPSLz
    import React from ‘react’;
    import {whyDidYouUpdate} from 'why-did-you-update';
    whyDidYouUpdate(React); // monkey patches for React

    View full-size slide

  23. w 1SPQTJTJNNVUBCMF Wʙ

    w 0CKFDUGSFF[F!EFW Wʙ

    w "EEFE3FBDUDMPOF&MFNFOU Wʙ

    w TFU1SPQTBOESFQMBDF1SPQTIBWFHPOF W

    w 1SPQ5ZQFTJTBMFHBDZGFBUVSF
    w :PVDBOVTF'MPXPS5ZQF4DSJQUJOTUFBE JNDPNQBUJCMF

    w *UNBZCFDPNFBTFQBSBUFEQBDLBHF
    1SPQT

    View full-size slide

  24. DPSFOPUFT.BZ

    View full-size slide

  25. w TFU4UBUFCFIBWFTBTCBUDIFE6QEBUFTJO&WFOU-JTUFOFS
    BOEMJGFDZDMFNFUIPET
    w :PVDBOQBTTBGVODUJPOUPTFU4UBUFGPSUSBOTBDUJPOBM
    VQEBUFT Wʙ

    4UBUF
    onClick() {
    this.setState((state, props) => ({count: state.count + 1}));
    this.setState((state, props) => ({count: state.count + 1}));
    }

    View full-size slide

  26. w UIFGPMMPXJOHFYBNQMF SFOEFSPDDVSTUXPUJNFT
    w /PCBUDIFE6QEBUFT
    "QJUGBMMPGCBUDIFE6QEBUFT
    onClick() {
    fetch(API_URL)
    .then(res => res.json())
    .then(json => {
    this.setState({user: json.user});
    // …
    this.setState({completed: true});
    });
    }

    View full-size slide

  27. w 3FBDU%0.VOTUBCMF@CBUDIFE6QEBUFTQSPWJEFT
    CBUDIFE6QEBUFT:PVDBOBWPJEVOOFDFTTBSZSFOEFST
    w *U`TVOTUBCMF#VUUIF"1*JTVTFECZ3FMBZFUD
    VOTUBCMF@CBUDIFE6QEBUFT
    onClick() {
    fetch(API_URL)
    .then(res => res.json())
    .then(json => {
    ReactDOM.unstable_batchedUpdates(() => {
    this.setState({user: json.user});
    // …
    this.setState({completed: true});
    });
    });
    }

    View full-size slide

  28. 3FBDU&MFNFOU

    View full-size slide

  29. w 3FBDUDSFBUF&MFNFOUSFUVSOTQMBJOPCKFDU Wʙ

    w /PNPSFTQBOBOEEBUBSFBDUJE FYDFQU443



    3FBDU&MFNFOU
    // Hello {name}

    Hello
    React


    Hello
    React

    View full-size slide

  30. w 4USJOH3FGJTMFHBDZ:PVTIPVMEVTFDBMMCBDL3FG
    w %0.$PNQPOFOUTSFUVSOJUT%0./PEFBT3FG
    w HFU%0./PEFTIBTHPOF W

    w 3FBDU%0.pOE%0./PEFTSFUVSOTB%0./PEFGSPN
    $PNQPTJUF$PNQPOFOUT
    3FG%0.
    render() {
    let text;
    return (

    c && c.focus()} />
    text = c} />

    );
    }

    View full-size slide

  31. w $POUFYUCFDPNFTBEPDVNFOUFEGFBUVSF
    w IUUQGBDFCPPLHJUIVCJPSFBDUEPDTDPOUFYUIUNM
    w *U`TBGFBUVSFGPS3FBDUMJCSBSJFT
    $POUFYU
    const Item = ({item}, {settings}) => (
    {item.name}
    );
    Item.contextTypes = {
    settings: React.PropTypes.object
    };

    View full-size slide

  32. w 8FDBOHFU4IBMMPX3FOEFSFS W

    w :PVDBOUFTUGPS3FBDU$PNQPOFOUTPO/PEF
    FOWJSPONFOU
    w *UEPFTO`UTVQQPSU3FGBOEMJGFDZDMFNFUIPETDPNQMFUFMZ
    w *U`TBl4IBMMPXzSFOEFSJOH
    5FTU
    const shallowRenderer = TestUtils.createRenderer();
    const elementTree = shallowRenderer.render();
    assert(elementTree.props.children[0].type === ‘div’);

    View full-size slide

  33. w 5FTUJOHVUJMJUJFTGPS3FBDU$PNQPOFOUT
    w TIBMMPX NPVOU SFOEFS
    w :PVDBOUFTUGPS3FBDU$PNQPOFOUFBTJMZBOE
    NBJOUBJOBCMF
    BJSCOCFO[ZNF
    import {shallow} from ‘enzyme’;
    const wrapper = shallow();
    assert(wrapper.find(Link).prop(‘to’) === ‘/foo’);
    wrapper.find(‘button’).simulate(‘click’);

    View full-size slide

  34. w %PFT&O[ZNFCFDPNFUIFP⒏DJBM5FTU6UJMT
    BJSCOCFO[ZNF
    core-notes

    May 05.

    View full-size slide

  35. w &4-JOUIFMQTZPVUPDSFBUF3FBDU$PNQPOFOUT
    w FTMJOUQMVHJOSFBDU
    w 3FBDUTQFDJpDMJOUJOHSVMFTGPS&4-JOU
    w IUUQTHJUIVCDPNZBOOJDLDSFTMJOUQMVHJOSFBDU
    w FTMJOUQMVHJOKTYBZ
    w 4UBUJD"45DIFDLFSGPSBDDFTTJCJMJUZSVMFTPO+49FMFNFOUT
    w IUUQTHJUIVCDPNFWDPIFOFTMJOUQMVHJOKTYBZ
    &4-JOU3FBDU

    View full-size slide

  36. &4-JOU3FBDU
    w OPTUSJOHSFGT
    w QSFGFSFTDMBTT
    w QSFGFSTUBUFMFTTGVODUJPO
    w OPEJSFDUNVUBUJPOTUBUF
    w TPSUDPNQ
    w KTYOPCJOE
    w KTYLFZ

    View full-size slide

  37. w 3FBDU/BUJWFIBTBIVHFFDPTZTUFN
    w 'BDFCPPLJTVTJOH3FBDU/BUJWFJO'BDFCPPLBQQ
    3FBDU/BUJWF

    View full-size slide

  38. w 3FBDU/BUJWFJTKVTUBSFOEFSFS
    3FBDU/BUJWF
    import React, {Component} from 'react';
    import {TabBarIOS, NavigatorIOS} from ‘react-native’;
    class App extends Component {
    render() {
    return (





    );
    }
    }

    View full-size slide

  39. w 3FBDU/BUJWFJTKVTUBSFOEFSFS
    3FBDU/BUJWF
    (facebook/react)
    src
    !"" isomorphic
    # !"" children
    # !"" classic
    # $"" modern
    !"" renderers
    # !"" art
    # !"" dom
    # # !"" client
    # # !"" server
    # # $"" shared
    # !"" native
    # !"" noop
    # $"" shared
    !"" shared

    View full-size slide

  40. NBLFJUPQFODPN

    View full-size slide

  41. "SDIJUFDUVSF

    View full-size slide

  42. w IUUQTHJUIVCDPNSFBDUKTSFBDUCBTJD
    SFBDUCBTJT

    View full-size slide

  43. w IUUQTHJUIVCDPNJBNEVTUBOUJOZSFBDUSFOEFSFS
    w "NJOJNVNJNQMFNFOUBUJPOPG3FBDU3FOEFSFS
    5JOZ3FBDU3FOEFSFS

    View full-size slide

  44. w :PVTIPVMEXBUDISFBDUKTDPSFOPUFT
    w 3FBDUXJMMSFMFBTFOFXNJOPSPSQBUDIWFSTJPOTFWFSZUXP
    XFFLT
    w 5PBEPQU&NCFSMJLF3'$QSPDFTT
    w &YQFSJNFOUJOHXJUI4UZMF4IFFUDSFBUF
    POUIFXFC
    w /FX3FDPODJMFS
    w 3FBDU$PSFJTNPSFTJNQMFS
    'VUVSF

    View full-size slide

  45. <8*1>/FX$PSF"MHPSJUIN

    View full-size slide

  46. /FX$PSF"MHPSJUIN

    View full-size slide

  47. /FX3FDPODJMFS*OGSB

    View full-size slide

  48. <'JCFS>$IJME3FDPODJMFS/FX$PSPVUJOFT
    1SJNJUJWF

    View full-size slide

  49. w 4DIFEVMJOH3FBDUSFDVSTJWFSFOEFSJOH
    w $VSSFOUMZ SFDVSTJWFSFOEFSJOHJTTZODISPOPVT XIJDIJTB
    SFBTPO3FBDUJTTMPX
    <8*1>/FX3FDPODJMFS
    // src/renderers/noop/ReactNoop.js
    var NoopRenderer = ReactFiberReconciler({
    createHostInstance() {
    },
    scheduleHighPriCallback(callback) {
    scheduledHighPriCallback = callback;
    },
    scheduleLowPriCallback(callback) {
    scheduledLowPriCallback = callback;
    },

    View full-size slide

  50. <8*1>/FX3FDPODJMFS
    function Continuation({ isSame }) {
    return {isSame ? 'foo==bar' : 'foo!=bar'};
    }
    function Child({ bar }) {
    return ReactCoroutine.createYield({
    bar: bar,
    }, Continuation, null);
    }
    function Indirection() {
    return [, ];
    }
    function HandleYields(props, yields) {
    return yields.map(y =>

    );
    }
    function Parent(props) {
    return ReactCoroutine.createCoroutine(
    props.children,
    HandleYields,
    props
    );
    }
    function App() {
    return ;
    }
    ReactNoop.render();
    ReactNoop.flush();

    View full-size slide

  51. <8*1>/FX3FDPODJMFS

    View full-size slide

  52. <8*1>/FX3FDPODJMFS
    w 3FTPVSDFT
    w IUUQTHJUIVCDPNSFBDUKTSFBDUCBTJD
    w IUUQTHJUIVCDPNSFBDUKTSFBDUGVUVSFCMPCNBTUFS
    -BZPVUQSPUPUZQFJOEFYKT

    View full-size slide

  53. 5IBOLZPV
    TQFBLFSEFDLDPNLPCB

    View full-size slide