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 Slide

  2. View Slide

  3. w XJMMCFIFMEJO+VOF
    "3FBDUKTNFFUVQPSHBOJ[FS

    View Slide

  4. 3FBDU&VSPQFJO1BSJT✈

    View Slide

  5. 8IPVTFT3FBDUKT

    View Slide

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

    View Slide

  7. *OTUBHSBN

    View Slide

  8. /FUqJY

    View Slide

  9. 5XJUUFS NPCJMF

    View Slide

  10. BJSCOC

    View Slide

  11. VCFS

    View Slide

  12. 3FBDUKTJTBCBUUMFUFTUFEMJCSBSZ
    GBDFCPPLVTFT3FBDUPONBTUFSCSBODIBUGBDFCPPLDPN

    View Slide

  13. 5IFIJTUPSZPG3FBDUKT

    View Slide

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

  15. 8IZ3FBDU

    View Slide

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

    View Slide

  17. $PNQPOFOU

    View Slide

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

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

    View Slide

  20. &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 Slide

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

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

  23. DPSFOPUFT.BZ

    View Slide

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

    View Slide

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

    It’s a PureRenderMixin for ES Classes.

    View Slide

  26. "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 Slide

  27. "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 Slide

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

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

  30. 1SPQT

    View Slide

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

  32. DPSFOPUFT.BZ

    View Slide

  33. 4UBUF

    View Slide

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

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

  36. w 3FBDU%[email protected]
    CBUDIFE6QEBUFT:PVDBOBWPJEVOOFDFTTBSZSFOEFST
    w *U`TVOTUBCMF#VUUIF"1*JTVTFECZ3FMBZFUD
    [email protected]
    onClick() {
    fetch(API_URL)
    .then(res => res.json())
    .then(json => {
    ReactDOM.unstable_batchedUpdates(() => {
    this.setState({user: json.user});
    // …
    this.setState({completed: true});
    });
    });
    }

    View Slide

  37. 3FBDU&MFNFOU

    View Slide

  38. w 3FBDUDSFBUF&MFNFOUSFUVSOTQMBJOPCKFDU Wʙ

    w /PNPSFTQBOBOEEBUBSFBDUJE FYDFQU443



    3FBDU&MFNFOU
    // Hello {name}

    Hello
    React


    Hello
    React

    View Slide

  39. 3FG%0.

    View Slide

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

  41. $POUFYU

    View Slide

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

    View Slide

  43. 5FTU

    View Slide

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

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

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

    May 05.

    View Slide

  47. &4-JOU3FBDU

    View Slide

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

    View Slide

  49. &4-JOU3FBDU

    View Slide

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

    View Slide

  51. 3FBDU/BUJWF

    View Slide

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

    View Slide

  53. 3FBDU/BUJWF

    View Slide

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





    );
    }
    }

    View Slide

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

    View Slide

  56. NBLFJUPQFODPN

    View Slide

  57. "SDIJUFDUVSF

    View Slide

  58. w IUUQTHJUIVCDPNSFBDUKTSFBDUCBTJD
    SFBDUCBTJT

    View Slide

  59. w IUUQTHJUIVCDPNJBNEVTUBOUJOZSFBDUSFOEFSFS
    w "NJOJNVNJNQMFNFOUBUJPOPG3FBDU3FOEFSFS
    5JOZ3FBDU3FOEFSFS

    View Slide

  60. 'VUVSF

    View Slide

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

    View Slide

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

    View Slide

  63. /FX$PSF"MHPSJUIN

    View Slide

  64. /FX3FDPODJMFS*OGSB

    View Slide

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

    View Slide

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

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

  68. <8*1>/FX3FDPODJMFS

    View Slide

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

    View Slide

  70. 5IBOLZPV
    TQFBLFSEFDLDPNLPCB

    View Slide