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

React.js v0.13 changes and beyond

koba04
March 30, 2015

React.js v0.13 changes and beyond

koba04

March 30, 2015
Tweet

More Decks by koba04

Other Decks in Programming

Transcript

  1. 3FBDUKTWDIBOHFTBOECFZPOE
    (VOPTZ3FBDU.FFUVQ

    !LPCB

    View full-size slide

  2. !LPCB
    w 8FC"QQMJDBUJPO&OHJOFFS
    w IUUQLPCBDPN
    w Ұਓ3FBDUKT"EWFOU$BMFBOEBS
    w IUUQRJJUBDPNBEWFOUDBMFOEBSSFBDUKT

    View full-size slide

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

    View full-size slide

  4. http://blog.koba04.com/post/2015/03/05/react-js-v013-changes/

    View full-size slide

  5. &4$MBTTFT
    class Hello extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    count: 0
    };

    }
    static get propTypes() {
    title: React.PropTypes.string.isRequired
    }
    onClick() { this.setState({ count: this.state.count + 1 }) }
    render() {
    return (

    {this.props.title}
    click
    {this.state.count}

    );
    }
    }

    View full-size slide

  6. &4$MBTTFT
    w HFU*OJUJBM4UBUFͰ͸ͳ͘ɺDPOTUSVDUPSͰTUBUFͷॳظ஋Λࢦఆ
    w BVUPCJOEJOH͞Εͳ͘ͳͬͨ
    w NJYJO͸ݱ࣌఺Ͱະαϙʔτ
    w IUUQTNFEJVNDPN!EBO@BCSBNPWNJYJOTBSFEFBEMPOHMJWFIJHIFS
    PSEFSDPNQPOFOUTBEGF
    w HFU%0./PEFɺJT.PVOUFEɺSFQMBDF1SPQTɺ
    SFQMBDF4UBUFɺTFU1SPQT͸EFQSFDBUFE

    View full-size slide

  7. 1SPQJTJNNVUBCMF

    View full-size slide

  8. 1SPQJTJNNVUBCMF
    w 1SPQͷ஋Λมߋ͠Α͏ͱ͢ΔͱXBSOJOH͕ग़ΔΑ͏ʹͳͬͨ
    w WͰ1SPQ͕*NNVUBCMFͰ͋Δ͜ͱΛલఏͱͨ͠ύϑΥʔϚ
    ϯεɾνϡʔχϯάΛ͢Δ͜ͱ͕໨త
    render() {
    // Warning: Don't set .props.level of the React component. …
    var title = ;
    if (this.state.isImportant) title.props.level = 2;
    };

    View full-size slide

  9. 1SPQTJTJNNVUBCMF
    w TIPVME$PNQPOFOU6QEBUFͰมߋΛݕग़ग़དྷͳ͍
    w UIJTQSPQTͱҾ਺Ͱ౉͞ΕΔOFYU1SPQT͕ಉ͡ʹͳΔ
    w 3FBDUDSFBUF&MFNFOUҎޙ͸มߋ͞Εͳ͍͜ͱΛอূ͍ͨ͠
    w 1SPQ5ZQFTͷνΣοΫ΋DSFBUF&MFNFOUͷ࣌ʹߦ͑͹Α͘
    ͳΔ
    w ωετͨ͠1SPQͷ஋ʹ͍ͭͯ͸ର৅֎
    w ৚݅ʹΑͬͯ1SPQ͕ม͍͑ͨ৔߹͸ɺ3FBDUDSFBUF&MFNFOU
    ʹ౉͢1SPQΛ࡞Δ·Ͱʹ౉ͤ͹͍͍

    View full-size slide

  10. 1SPQJTJNNVUBCMF
    if (shouldUseFoo) {
    return ;
    } else {
    return ;
    }
    or
    var props = { bar: false };
    if (shouldUseFoo) {
    props.foo = 10;
    props.bar = true;
    }
    return ;

    View full-size slide

  11. TFU4UBUFDBOUBLFBGVODUJPOBTTUBSHVNFOU
    w τϥϯβΫγϣϯ͕ඞཁͱ͞ΕΔσʔλͷߋ৽ʹ࢖͏
    w ͜Ε·Ͱ͸@QFOEJOH4UBUFΛ࢖͏ඞཁ͕͋ͬͨ
    console.log(this.state.count) // 0
    this.setState({count: this.state.count + 1})
    this.setState({count: this.state.count + 1})
    // state.count will render as 1
    console.log(this.state.count) // 0
    this.setState(function(state, props) {
    return {count: state.count + 1}
    });
    this.setState(function(state, props) {
    return {count: state.count + 1}
    });
    // state.count will render as 2

    View full-size slide

  12. TFU4UBUFJTBMXBZTBTZODISPOPVT
    w ͜Ε·ͰॳճͷϚ΢ϯτ࣌ͷݺͼग़͠͸ಉظత͚ͩͬͨͲৗʹ
    ඇಉظͰ#BUDIVQEBUFʹͳΔ
    componentDidMount() {
    console.log(this.state.count) // 0
    this.setState({ count: this.state.count + 1 })
    this.setState({ count: this.state.count + 1 })
    console.log(this.state.count)
    ɹ// v0.12 is 2
    ɹ// v0.13 is 0
    }

    View full-size slide

  13. TFU4UBUFPOVONPVOUFEDPNQPOFOU
    w ΞϯϚ΢ϯτ͞ΕͨDPNQPOFOUͰͷTFU4UBUF GPSDF6QEBUF

    ͷݺͼग़ͨ࣌͠ʹΤϥʔͰͳ͘XBSOJOH͕ग़ྗ͞ΕΔΑ͏ʹ
    w "KBYʹର͢ΔϨεϙϯεΛTFU4UBUF͢ΔΑ͏ͳͱ͖ʹ
    JT.PVOUFEͰϒϩοΫ͢Δඞཁ͕ͳ͘ͳͬͨ
    request(‘/api/users/koba04’, (res) => {
    // if (this.isMounted()) {
    this.setState({ user: res.body.user });
    // }
    });

    View full-size slide

  14. 3FBDUpOE%0./PEF

    View full-size slide

  15. pOE%0./PEFJOTUFBEPGHFU%0./PEF
    w HFU%0./PEF͸&4$MBTTFTͰ͸ఏڙ͞Εͯͳ͍͠
    DSFBUF$MBTTͰ΋XBSOJOH͕ग़ΔͷͰஔ͖׵͑Δ
    class Sample extends React.Component {
    onClick() {
    this.setState({
    // text: this.refs.inputText.getDOMNode().value
    text: React.findDOMNode(this.refs.inputText).value
    });
    }
    render() {
    return(


    click

    );
    }
    }

    View full-size slide

  16. 0XOFSDPOUFYUUP1BSFOU$POUFYU

    View full-size slide

  17. 0XOFSBOE1BSFOU
    w 1BSFOUͱ0XOFS͕Ұக͠ͳ͍DPOUFYUΛ࢖͓͏ͱ͢Δͱ
    XBSOJOH͕ग़ΔΑ͏ʹͳͬͨ
    w 1BSFOUϕʔεͷDPOUFYU͸·࣮ͩ૷͞Ε͍ͯͳ͍
    w 0XOFS 1BSFOU DPOUFYU
    w VOEPDVNFOUFEGFBUVSF

    View full-size slide

  18. 0XOFSBOE1BSFOU
    const p = title;
    class Hoge extends React.Component {
    render() {
    return (

    {p}
    hello

    );
    }
    }
    span: owner is Hoge, parent is div ! Hoge
    p: owner is null, parent is div ! Hoge

    View full-size slide

  19. $POUFYU
    const Parent React.createClass({
    static get childContextTypes() {
    return { name: React.PropTypes.string }
    }
    getChildContext() { return { name: ‘parent’ } }
    render() { return }
    }
    // Child render
    class GrandChild extends React.Component {
    static get contextTypes() {
    return { name: React.PropTypes.string }
    }
    render() {
    {this.context.name}
    }
    }

    View full-size slide

  20. $POUFYU
    const child = ;
    const Parent React.createClass({
    static get childContextTypes() {
    return { name: React.PropTypes.string }
    }
    getChildContext() { return { name: ‘parent’ } }
    render() { return {child} }
    }
    class Child extends React.Component {
    static get contextTypes() {
    return { name: React.PropTypes.string }
    }
    render() {
    {this.context.name}
    }
    }
    React.render(, document.getElementById(‘app’));
    // Warning: owner-based and parent-based contexts differ

    View full-size slide

  21. SFBDUSPVUFSXJUIDPOUFYU
    // 0.12.x
    var Foo = React.createClass({
    mixins: [ Router.State ],
    render: function () {
    var id = this.getParams().id;
    // etc. ...
    }
    });
    // 0.13.x w/ ES6 fanciness
    class Foo extends React.Component {
    render () {
    var { router } = this.context;
    var id = router.getCurrentParams().id;
    // etc.
    }
    }
    Foo.contextTypes = {
    router: React.PropTypes.func
    };

    View full-size slide

  22. SFGDBOQBTTBDBMMCBDL
    class Hello extends React.Component {
    onClick() {
    this.setState({
    text: React.findDOMNode(this._inputText).value
    });
    }
    render() {
    return (

    this._inputText = c} />
    click

    );
    }
    }
    w طଘͷSFGlYYYz΋ͦͷ··࢖͑Δ 0XOFSDPOUFYU

    View full-size slide

  23. 3FBDUDMPOF&MFNFOU

    View full-size slide

  24. 3FBDUDMPOF&MFNFOU
    w 3FBDUBEEPOTDMPOF8JUI1SPQTʹ͍ۙ
    w 1SPQͱ*NNVUBCMFͱͯ͠ѻ͏͜ͱͰDMPOF͢Δ৔໘͕૿͑Δ
    ͨΊɺίΞͷ"1*ʹͳͬͨ
    w ҧ͍ͱͯ͠͸TUZMF΍DMBTT/BNFͷNFSHF͸ߦΘΕͣɺSFG͕อ
    ࣋͞ΕΔ
    var newChildren = React.Children.map(
    this.props.children,
    child => React.cloneElement(child, { foo: true })
    );

    View full-size slide

  25. 4VQQPSUJUFSBUPSTBTDIJMESFO
    w JUFSBUPSΛͦͷ··౉͢͜ͱ͕ग़དྷΔ
    w *NNVUBCMFKTͷ-JTUΛNBQͨ͠΋ͷΛࠓ·Ͱ͸UP"SSBZͨ͠Γ
    ͢Δඞཁ͕͋ͬͨͷ͕ͦͷ··౉ͤΔ
    render() {

    {Immutable.List([1,2,3]).map(i => {i})}

    }

    View full-size slide

  26. ,FZFE0CKFDU
    w \LFZFMFNFOU^ΛDIJMESFOʹ౉͢ͱXBSOJOH͕ग़ΔΑ͏ʹͳͬ
    ͨ
    w ௥Ճ͞Εͨ3FBDUBEEPOTDSFBUF'SBHNFOUΛ࢖ͬͨΓNBQͰ
    ճͨ͠Γ͢Ε͹͍͍
    // Keyed Object
    { {a: , b: } }
    // ===
    {React.addons.createFragment({a: , b: })

    View full-size slide

  27. UBSHFUPQUJPO
    w EFGBVMU͸FTɻ͜Ε·Ͱͷڍಈʹ͢ΔͳΒFTΛࢦఆ͢Δ
    w FT͕EFGBVMUʹͳΓͦ͏ͳྲྀΕ͚ͩͬͨͲɺ!TFCNDL͕FT
    ΛEFGBVMUʹ͢ΔΑ͏ʹ͍࣋ͬͯͬͨ

    View full-size slide

  28. UBSHFUPQUJPO
    w &4DMBTTFTͰॻ͍ͨ࣌ͷϝιου͕FOVNFSBCMF͔Ͳ͏͔ͷ
    ҧ͍͕͋Δ
    class Hello extends React.Component {
    foo() {
    console.log("foo");
    }
    render() {
    return hello;
    }
    }

    View full-size slide

  29. UBSHFUFT
    var ____Class0=React.Component;for(var ____Class0____Key in ____Class0)
    {if(____Class0.hasOwnProperty(____Class0____Key))
    {Hello[____Class0____Key]=____Class0[____Class0____Key];}}var
    ____SuperProtoOf____Class0=____Class0===null?
    null:____Class0.prototype;Hello.prototype=Object.create(____SuperProtoOf____C
    lass0);Hello.prototype.constructor=Hello;Hello.__superConstructor__=____Class
    0;function Hello(){"use strict”;if(____Class0!==null)
    {____Class0.apply(this,arguments);}}
    Object.defineProperty(Hello.prototype,"foo",
    {writable:true,configurable:true,value:function() {"use strict";
    console.log("foo");
    }});
    Object.defineProperty(Hello.prototype,"render",
    {writable:true,configurable:true,value:function() {"use strict";
    return React.createElement("div", null, "hello");
    }});

    View full-size slide

  30. UBSHFUFT
    var ____Class0=React.Component;for(var ____Class0____Key in ____Class0)
    {if(____Class0.hasOwnProperty(____Class0____Key))
    {Hello[____Class0____Key]=____Class0[____Class0____Key];}}var
    ____SuperProtoOf____Class0=____Class0===null?
    null:____Class0.prototype;Hello.prototype=Object.create(____SuperProtoOf____C
    lass0);Hello.prototype.constructor=Hello;Hello.__superConstructor__=____Class
    0;function Hello(){"use strict”;if(____Class0!==null)
    {____Class0.apply(this,arguments);}}
    Hello.prototype.foo=function() {"use strict";
    console.log("foo");
    };
    Hello.prototype.render=function() {"use strict";
    return React.createElement("div", null, "hello");
    };

    View full-size slide

  31. w ͱ^͕Ҏલ͸จࣈྻͱͯ͠ѻΘΕ͍͚ͯͨͲQBSTFΤϥʔʹ
    ͳΔΑ͏ʹͳͬͨ
    BOE^BSFUSFBUFEBTBQBSTFFSSPS
    render() {
    return 10 > 2; // parse error!
    }

    View full-size slide

  32. 4IBMMPXSFOEFSJOH EPDVNFOUFE

    View full-size slide

  33. 4IBMMPXSFOEFSJOH
    w ֊૚·ͰΛSFOEFSͯ݁͠ՌΛฦ͢5FTU6UJMT
    w OPEF؀ڥͰ΋ಈ࡞͢Δ
    w SFOEFSϝιουͷ݁ՌΛ֬ೝ͍ͨ͠ͱ͖ʹศར

    View full-size slide

  34. 4IBMMPXSFOEFSJOH
    class Parent extends React.Component {
    render() {
    return ;
    }
    }
    class Child extends React.Component {
    render() {
    return {this.props.name};
    }
    }
    const shallowRenderer = React.addons.TestUtils.createRenderer();
    shallowRenderer.render();
    const result = shallowRenderer.getRenderOutput();
    console.assert(result.type === 'div');
    console.assert(result.props.children.type === Child);
    console.assert(result.props.children.props.name === 'child');
    console.assert(result.props.children.props.children === undefined);
    ➜ babel-node test.js

    View full-size slide

  35. 3FBDUKTW 1MBO

    View full-size slide

  36. 3FVTF$POTUBOU7BMVF5ZQFT
    w ಉ͡3FBDU&MFNFOUΛ࢖͍·Θ͢͜ͱͰEJ⒎ͷίετΛݮΒ͢
    w SFOEFS͸Կ౓΋ݺ͹Εͯͦͷ౓ʹ3FBDU&MFNFOU͕࡞ΒΕΔ
    function render() {
    return ;
    }
    // ͜͏΍ͬͯίϯύΠϧ͢Δ(Πϝʔδ)
    var div = React.createElement("div", {className: “foo”});
    function render() {
    return div;
    }

    View full-size slide

  37. 5BHHJOH3FBDU&MFNFOUT
    w 3FBDU&MFNFOUʹUBH෇͚Λͯ͠ɺEJ⒎ΞϧΰϦζϜΛ࠷దԽ͢
    Δ
    {c}
    // ͜͏΍ͬͯίϯύΠϧ͢Δ(Πϝʔδ)
    { __t: 7, type: 'div', props: { className: 'foo', style: { width: w, height:
    5 }, children: c } }
    // ·ͨ͸
    var t = { className: 1, style: { height: 1 } };
    { __t: t, type: 'div', props: { className: 'foo', style: { width: w, height:
    5 }, children: c } }

    View full-size slide

  38. *OMJOF3FBDU&MFNFOUT
    w QSPEVDUJPOϏϧυͷ͚࣌ͩɺ3FBDUDSFBUF&MFNFOUͰ͸ͳ͘
    ͯJOMJOFPCKFDUʹม׵͢Δ͜ͱͰίετΛݮΒ͢
    w DSFBUF&MFNFOU࣌ͷ1SPQ5ZQFTʹΑΔνΣοΫ͸Ͱ͖ͳ͘ͳΔ
    ͷͰQSPEVDUJPOϏϧυͷ͚࣌ͩ
    {bar}
    // ͜͏΍ͬͯίϯύΠϧ͢Δ(Πϝʔδ)
    { type: 'div', props: { className: 'foo', children:
    [ bar, { type: Baz, props: { }, key: 'baz', ref: null } ]
    }, key: null, ref: null }

    View full-size slide

  39. 0CTFSWBCMF"1*
    w IUUQTHJUIVCDPNGBDFCPPLSFBDUJTTVFT
    class Foo {
    observe() {
    return {
    user: loadUser(this.props.userID)
    };
    }
    render() {
    if (this.data.user.id !== this.props.userID) {
    // Ensure that we never show inconsistent userID / user.name
    combinations.
    return ;
    }
    return Hello, {this.data.user.name} [{this.props.userID}]!;
    }
    }

    View full-size slide

  40. 3FBDU—1BSTF
    w IUUQCMPHQBSTFDPNQBSTFBOESFBDUTIBSFEDIFNJTUSZ
    // Render a list of comments from the Parse API
    var CommentBlock = React.createClass({
    mixins: [ParseReact.Mixin],
    observe: function() {
    return {
    comments: (new Parse.Query('Comment')).descending('createdAt')
    };
    },
    render: function() {
    return
    {this.data.comments.map(function(c) {
    return {c.text}
    })}
    ;
    }
    });

    View full-size slide

  41. 7FSTJPOJOH
    w ݱࡏ
    w 9ͰEFQSFDBUJPOXBSOJOHTɺ9Ͱ"1*࡟আ
    w Ҡߦ
    w 9:ͰEFQSFDBUJPOXBSOJOHTɺ9Ͱ"1*࡟আ
    w IUUQTHJTUHJUIVCDPN[QBPFFFGDFBG

    View full-size slide

  42. http://facebook.github.io/react/blog/2014/03/28/the-road-to-1.0.html

    View full-size slide

  43. 3FBDUKTW
    w ͢ͰʹQSPEVDUJPOSFBEZ
    w $POUFYUͲ͏͢Δ͔
    w "EEPOTͷ੔ཧɾ֎෦ϥΠϒϥϦԽ
    w "OJNBUJPOͷվળ
    w ʜ

    View full-size slide

  44. 5IBOLZPV
    TQFBLFSEFDLDPNLPCB

    View full-size slide