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. &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 ( <div> <p>{this.props.title}</p> <button onClick={this.onClick.bind(this)}>click</button> <p>{this.state.count}</p> </div> ); } }
  2. 1SPQJTJNNVUBCMF w 1SPQͷ஋Λมߋ͠Α͏ͱ͢ΔͱXBSOJOH͕ग़ΔΑ͏ʹͳͬͨ w WͰ1SPQ͕*NNVUBCMFͰ͋Δ͜ͱΛલఏͱͨ͠ύϑΥʔϚ ϯεɾνϡʔχϯάΛ͢Δ͜ͱ͕໨త render() { // Warning:

    Don't set .props.level of the React component. … var title = <title level={1} />; if (this.state.isImportant) title.props.level = 2; };
  3. 1SPQJTJNNVUBCMF if (shouldUseFoo) { return <Foo foo={10} bar={true} />; }

    else { return <Foo bar={false} />; } or var props = { bar: false }; if (shouldUseFoo) { props.foo = 10; props.bar = true; } return <Foo {...props} />;
  4. 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
  5. 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 }
  6. 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( <div> <input type=“text” ref=“inputText” /> <button onClick={this.onClick.bind(this)}>click</button> </div> ); } }
  7. 0XOFSBOE1BSFOU const p = <p>title</p>; class Hoge extends React.Component {

    render() { return ( <div> {p} <span>hello</span> </div> ); } } span: owner is Hoge, parent is div ! Hoge p: owner is null, parent is div ! Hoge
  8. $POUFYU const Parent React.createClass({ static get childContextTypes() { return {

    name: React.PropTypes.string } } getChildContext() { return { name: ‘parent’ } } render() { return <Child /> } } // Child render <GrandChild /> class GrandChild extends React.Component { static get contextTypes() { return { name: React.PropTypes.string } } render() { <div>{this.context.name}</div> } }
  9. $POUFYU const child = <Child />; const Parent React.createClass({ static

    get childContextTypes() { return { name: React.PropTypes.string } } getChildContext() { return { name: ‘parent’ } } render() { return <div>{child}</div> } } class Child extends React.Component { static get contextTypes() { return { name: React.PropTypes.string } } render() { <div>{this.context.name}</div> } } React.render(<Parent />, document.getElementById(‘app’)); // Warning: owner-based and parent-based contexts differ
  10. 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 };
  11. SFGDBOQBTTBDBMMCBDL class Hello extends React.Component { onClick() { this.setState({ text:

    React.findDOMNode(this._inputText).value }); } render() { return ( <div> <input type=“text” ref={(c) => this._inputText = c} /> <button onClick={this.onClick.bind(this)}>click</button> </div> ); } } w طଘͷSFGlYYYz΋ͦͷ··࢖͑Δ 0XOFSDPOUFYU
  12. ,FZFE0CKFDU w \LFZFMFNFOU^ΛDIJMESFOʹ౉͢ͱXBSOJOH͕ग़ΔΑ͏ʹͳͬ ͨ w ௥Ճ͞Εͨ3FBDUBEEPOTDSFBUF'SBHNFOUΛ࢖ͬͨΓNBQͰ ճͨ͠Γ͢Ε͹͍͍ // Keyed Object

    <div>{ {a: <span />, b: <span />} }</div> // === <div><span key=“a” /><span key=“b” /></div> <div>{React.addons.createFragment({a: <span />, b: <span />})</div>
  13. +49

  14. 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"); }});
  15. 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"); };
  16. 4IBMMPXSFOEFSJOH class Parent extends React.Component { render() { return <div><Child

    name=“child” /></div>; } } class Child extends React.Component { render() { return <div>{this.props.name}</div>; } } const shallowRenderer = React.addons.TestUtils.createRenderer(); shallowRenderer.render(<Parent />); 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 ➜
  17. 3FVTF$POTUBOU7BMVF5ZQFT w ಉ͡3FBDU&MFNFOUΛ࢖͍·Θ͢͜ͱͰEJ⒎ͷίετΛݮΒ͢ w SFOEFS͸Կ౓΋ݺ͹Εͯͦͷ౓ʹ3FBDU&MFNFOU͕࡞ΒΕΔ function render() { return <div

    className="foo" />; } // ͜͏΍ͬͯίϯύΠϧ͢Δ(Πϝʔδ) var div = React.createElement("div", {className: “foo”}); function render() { return div; }
  18. 5BHHJOH3FBDU&MFNFOUT w 3FBDU&MFNFOUʹUBH෇͚Λͯ͠ɺEJ⒎ΞϧΰϦζϜΛ࠷దԽ͢ Δ <div className="foo" style={{ width: w, height:

    5 }}>{c}</div> // ͜͏΍ͬͯίϯύΠϧ͢Δ(Πϝʔδ) { __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 } }
  19. *OMJOF3FBDU&MFNFOUT w QSPEVDUJPOϏϧυͷ͚࣌ͩɺ3FBDUDSFBUF&MFNFOUͰ͸ͳ͘ ͯJOMJOFPCKFDUʹม׵͢Δ͜ͱͰίετΛݮΒ͢ w DSFBUF&MFNFOU࣌ͷ1SPQ5ZQFTʹΑΔνΣοΫ͸Ͱ͖ͳ͘ͳΔ ͷͰQSPEVDUJPOϏϧυͷ͚࣌ͩ <div className="foo">{bar}<Baz key="baz"

    /></div> // ͜͏΍ͬͯίϯύΠϧ͢Δ(Πϝʔδ) { type: 'div', props: { className: 'foo', children: [ bar, { type: Baz, props: { }, key: 'baz', ref: null } ] }, key: null, ref: null }
  20. 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 <Spinner />; } return <div>Hello, {this.data.user.name} [{this.props.userID}]!</div>; } }
  21. 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 <ul> {this.data.comments.map(function(c) { return <li>{c.text}</li> })} </ul>; } });
  22. 7FSTJPOJOH w ݱࡏ w 9 ͰEFQSFDBUJPOXBSOJOHTɺ9 Ͱ"1*࡟আ w Ҡߦ w

    9:ͰEFQSFDBUJPOXBSOJOHTɺ9 Ͱ"1*࡟আ w IUUQTHJTUHJUIVCDPN[QBPFFFGDFBG