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

React/Reduxにおける現場での喜び/ツラみ

Ryota
February 24, 2016

 React/Reduxにおける現場での喜び/ツラみ

React.js meetup #3 (http://reactjs-meetup.connpass.com/event/26229/) におけるLT発表資料。
発表時に使用した資料からは加筆・修正しています。

Ryota

February 24, 2016
Tweet

Other Decks in Programming

Transcript

  1. Agenda 1. Intro 2. React/Redux における現場での喜び・ ツラみ 1. router どれ使えば良い?

    2. ES6 Modules とTesting 3. リファクタリングとPropTypes 3. Conclusion 2 / 30
  2. router どれ使えば良い? SPA において必要不可欠なrouter React/Redux におけるデファクトのrouter は? libs GitHub star

    react-router 10,695 react-router-redux a few month ago redux-simple-router 2,021 redux-router 1,484 counted on Feb 14, 2016 6 / 30
  3. react-router 1.x → 2.x のupdate でbreaking changes 有 history instance

    がsingleton mixins がdeprecated に programmatic navigation のsignature がsimple に etc v2.0.0 Upgrade Guide https://github.com/reactjs/react-router/blob/master/upgrade- guides/v2.0.0.md ドキュメントも豊富で、 使いやすくなっているので◎ 7 / 30
  4. Redux においてrouter はどうあるべきか? action: 何かが起こったというを説明するオブジェクト Three Principles @ redux docs

    http://redux.js.org/docs/introduction/ThreePrinciples.html URL(state) を変更したい! → URL を変更するときはaction をstore にdispatch すべき? 8 / 30
  5. reactjs/react-router-redux example i m p o r t { r

    o u t e A c t i o n s } f r o m ' r e a c t - r o u t e r - r e d u x ' ; / / a c t i o n c r e a t o r でa c t i o n を作って, s t o r e にd i s p a t c h < B u t t o n o n C l i c k = { ( ) = > d i s p a t c h ( r o u t e A c t i o n s . p u s h ( ' / f o o ' ) ) ; } / > i m p o r t { U P D A T E _ L O C A T I O N } f r o m ' r e a c t - r o u t e r - r e d u x ' ; f u n c t i o n s o m e R e d u c e r ( s t a t e , a c t i o n ) { s w i t c h ( a c t i o n . t y p e ) { c a s e U P D A T E _ L O C A T I O N : / / d o s o m e t h i n g } } 9 / 30
  6. 弊社のReact を使ったProject では... ES6 Modules 使ってますか? Yes Testing libraries は何使ってますか?

    mocha power-assert + espower-babel + ES6 jsdom Unit test でのmodules のMock どうやってますか? proxyquire を使っている https://github.com/thlorenz/proxyquire 13 / 30
  7. Babel6 shock ES6 default export のみで構成されるModule をCommonJS 形式でrequire する ときは注意が必要

    / / d e p s : a . j s e x p o r t d e f a u l t f u n c t i o n a ( ) { c o n s o l e . l o g ( ' H e l l o a ! ' ) ; } / / m a i n : m a i n . j s / / B a b e l 5 c o n s t a = r e q u i r e ( ' . / a ' ) ; / / B a b e l 6 c o n s t a = r e q u i r e ( ' . / a ' ) . d e f a u l t ; e x p o r t f u n c t i o n m a i n ( ) { a ( ) ; } 14 / 30
  8. Test でproxyquire を使っている場合 先ほどのBabel6 shock に受ける影響に加えて次の場合でもBabel5,Babel6 で書き方 を変えなければならない. テスト対象がdefault export

    のみから構成され, かつテスト対象Module の依存 Module をMock したいとき / / d e p s : a . j s e x p o r t d e f a u l t f u n c t i o n a ( ) { c o n s o l e . l o g ( ' H e l l o a ! ' ) ; } / / m a i n : m a i n . j s / / B a b e l 5 c o n s t a = r e q u i r e ( ' . / a ' ) ; / / B a b e l 6 c o n s t a = r e q u i r e ( ' . / a ' ) . d e f a u l t ; / / d e f a u l t e x p o r t のみから構成されるM o d u l e の依存a ( ) をM o c k したいとき e x p o r t d e f a u l t f u n c t i o n m a i n ( ) { a ( ) ; } 15 / 30
  9. Babel5 テスト対象: main.js(default export のみで構成されるES6 Module) が a.js(default export のみで構成されるES6

    Module) に依存している場合 i m p o r t p r o x y q u i r e f r o m ' p r o x y q u i r e ' ; c o n s t a S t u b = f u n c t i o n a ( ) { c o n s o l e . l o g ( ' M o c k h e l l o a ! ' ) ; } / / t e s t t a r g e t : m a i n ( d e f a u l t e x p o r t のみから構成されるE S 6 M o d u l e ) c o n s t s u t = p r o x y q u i r e ( ' p a t h / 2 / m a i n ' , { ' . / a ' : a S t u b } ) ; d e s c r i b e ( ' t e s t m a i n ' , ( ) = > { i t ( ' m a i n がa に依存している' , ( ) = > { s u t ( ) ; } ) ; } ) ; 16 / 30
  10. Babel6 テスト対象: main.js(default export のみで構成されるES6 Module) が a.js(default export のみで構成されるES6

    Module) に依存している場合 i m p o r t p r o x y q u i r e f r o m ' p r o x y q u i r e ' ; c o n s t a S t u b = { / / d e f a u l t e x p o r t のp a t h はd e f a u l t に d e f a u l t : f u n c t i o n a ( ) { c o n s o l e . l o g ( ' M o c k h e l l o a ! ' ) ; } } ; / / t e s t t a r g e t : m a i n ( d e f a u l t e x p o r t のみから構成されるE S 6 M o d u l e ) c o n s t s u t = p r o x y q u i r e ( ' p a t h / 2 / m a i n ' , { ' . / a ' : a S t u b } ) . d e f a u l t ; / / d e f a u l t が必要に d e s c r i b e ( ' t e s t m a i n ' , ( ) = > { i t ( ' m a i n がa に依存している' , ( ) = > { s u t ( ) ; } ) ; } ) ; 17 / 30
  11. PropTypes#shape shape を作って,PropTypes の修正箇所を局所化することもできるが... i m p o r t

    { P r o p T y p e s } f r o m ' r e a c t ' ; c o n s t e n t r y S h a p e = P r o p T y p e s . s h a p e ( { b o d y : P r o p T y p e s . s t r i n g . i s R e q u i r e d , e i d : P r o p T y p e s . n u m b e r . i s R e q u i r e d , p e r m a n e n t L i n k : P r o p T y p e s . s t r i n g . i s R e q u i r e d , p o s t e d A t : P r o p T y p e s . s t r i n g . i s R e q u i r e d , t i t l e : P r o p T y p e s . s t r i n g . i s R e q u i r e d , u r l F i r s t I m a g e : P r o p T y p e s . s t r i n g . i s R e q u i r e d , } ) ; e x p o r t d e f a u l t e n t r y S h a p e ; i m p o r t e n t r y S h a p e f r o m ' p a t h / 2 / e n t r y - s h a p e ' ; e x p o r t d e f a u l t c l a s s S o m e C o m p o n e n t e x t e n d s C o m p o n e n t { r e n d e r ( ) { / / b l a h b l a h } } S o m e C o m p o n e n t . p r o p T y p e s = { e n t r i e s : P r o p T y p e s . a r r a y O f ( e n t r y S h a p e ) . i s R e q u i r e d } ; 22 / 30
  12. PropTypes in the future Facebook member sebmarkbage said on Feb

    10th, 2016. https://github.com/facebook/react/issues/1833#issuecomment-182665824 25 / 30
  13. PropTypes in the future Flow 使ってprops のcheck 試してる人もいる. Replace React.PropTypes

    with Flow types #277 https://github.com/facebook/flow/issues/277 26 / 30
  14. Conclusion React におけるrouter は現状react-router2.x が良い. わざわざRedux の世界のrouter まで踏み込むメリットは薄い. 技術の導入は, 相性や順番に戦略が必要.

    例えばBabel6 移行とMock ライブラリの導入を考える場合は先にBabel6 対 応したほうが良いかも. ES6 Modules のご利用は計画的に. ES2015,ES2016,ES.Next 時代のModules Mock ライブラリには既存のMock と ES6 Modules のMock の仕組みの考慮が必要そう. React/Flux におけるメリットは捨てがたいのでツラみ等知見を共有したい. 28 / 30