「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>JavaScript#s4081e43]] *目次 [#f787db65] #contents *概要 [#dff610b2] -Facebook社が開発しているSingle Page Application開発用の[[UIサブシステム>#y5519e45]]。 -[[コンポーネント指向>#m9350bfc]]に基づいて効率的にSPAを開発できる。 -[[JSX>#ne8ad84a]](*.jsx、*.tsx)で作成され、[[Node.js]]開発環境でコンパイルされて*.jsを得る。 -下記の[[特徴>#d16b27fe]]を見ると、JSのMV*も[[XAML>https://techinfoofmicrosofttech.osscons.jp/index.php?XAML]]的になったなぁという感覚がある。 *特徴 [#d16b27fe] **Just the UI [#y5519e45] -View(UI)部分のみを管理する **コンポーネント指向 [#m9350bfc] -Reactでは「コンポーネント」を生成し組み合わせていくことでUIを構築する。 -なお、コンポーネントのインスタンスのことを「エレメント」と言う。 ***仮想DOM [#b5a85f5b] -設計と速度が両立すると言われている。 -仮想DOMの構造体表現と、それを用いたdiff/patchアルゴリズム。 --最終的に生成されるHTMLの複雑なDOMではなく、仮想的なDOMを記述する。 --2つのツリー構造のdiffを算出して、それをDOMにpatchするアクションを作る。 -[[JSX>#ne8ad84a]]で記述する。 ***Data flow [#i6a6e2f6] -コンポーネント中のデータの流れを --[[state>#j6338a61]], [[props>#wac86e94]] -- -> UI要素へ >と、一方向化している。 -詳しくは、[[Flux>#s9dbd4f8]]を参照。 *基本的な事項 [#b58a8b20] **JSX [#ne8ad84a] ***特徴 [#i7940c50] -JSの拡張言語で、 --React 要素作成する[[仮想DOM>#b5a85f5b]]を、簡便な形式でXMLマークアップのシンタックスを追加する。 --XMLマークアップには、標準のHTML5 + 拡張属性で、HTMLタグとJSXタグが共存する。 --制御構文とXMLマークアップが混在するという意味で、Razor的。 -Webページ内でJSXを使用するには、 --「[[Babel>JavaScript#f322ef90]]」([[ECMAScript]])を導入する方法が最も簡単。 --また、「[[TypeScript>JavaScript#kf4fe370]]」でもサポートされている(TSX)。 -プログラム・ファイルの拡張子 --[[Babel>JavaScript#f322ef90]]([[ECMAScript]])では、*.jsx。 --[[TypeScript>JavaScript#kf4fe370]]では、*.tsx。 ***変数出力 [#zd3c948e] {変数名}でJavaScript変数を出力 ***イベント・ハンドラ [#y2f3d04b] -基本的に以下のように書く。 <button onClick={()=>this.renderChange()}>切替</button> -以下は問題がある。 --レンダリング時にclickActionが起動してしまう。 <div onClick={this.clickAction()}> --thisにアクセスできない。 <div onClick={this.clickAction}> ***属性の指定 [#d3f420c0] 自由に属性を設定可能。 <div> <MyComponent myTitle={'タイトル'} myValue={this.state.value} /> </div> 子コンポーネントから[[props>#wac86e94]].(定義した属性名)と利用。 ***Css in JS [#p175ea2a] -React自信にデザインの機能はないのでCSSを利用する。 -「Css in JS」と言われる考え方が登場し、~ React用のCSSをインポート可能になっている。 -classはclassNameと書く。styleはstyleで良い。 <button className="btn btn-default" style={{color:"gray"}}/> ***コンポーネントの配置 [#o16e4347] [[JSX>#ne8ad84a]]タグでコンポーネントを設置 -タグ名=コンポーネントクラス名の -[[JSX>#ne8ad84a]]タグは頭文字を大文字になる。 <MyComponent /> ***コンポーネントのネスト [#h22a25e9] [[コンポーネントのRender>#w9dbdb36]]内に、子コンポーネントを記述 <SubComponent /> **基本形のコンポーネント [#z184f699] import React from 'react'; import ReactDOM from 'react-dom'; class MyComponent extends React.Component { constructor(props,context){ super(props,context) this.state = { viewText : 'テストページ' } } render(){ return ( <div> <h1>Hello! World.</h1> <p>このページは{ this.state.viewText }です。</p> </div> ) } } ***extends [#g161dea2] [[state>#j6338a61]], [[props>#wac86e94]]を使用する場合、React.Componentを継承する。 ***export [#w927d04f] -モジュール化することによってインポート可能なクラスにする。 export class MyComponent extends React.Component { -defaultも付けると、デフォルトで読み込むモジュールになる export default class MyComponent extends React.Component { ***import [#s62834cb] exportでモジュール化したクラスは、importでインポートが可能。 -1クラス、インポート import { SubComponent1 } from './SubComponent'; -nクラス、インポート(1ファイルに複数定義されている場合。 import { SubComponent1, SubComponent2 } from './SubComponent'; ***state [#j6338a61] -コンポーネントの状態を表す変数。 -コードからReact.Componentのプロパティと思われる。 ***props [#wac86e94] -データを親コンポーネントから子コンポーネントに渡す際に使用する。 -変更不可と書かれていることがあるが[[変更通知>#b6de5462]]を使用すれば変更可能。 -コードからReact.Componentのプロパティと思われる。 ***constructor [#ha6acf80] -[[state>#j6338a61]]あり constructor(props, context) { super(props, context) this.state = { viewText: props.text, viewFlg: props.defaultFlg, } } -[[state>#j6338a61]]なし~ [[state>#j6338a61]]を使わない、[[props>#wac86e94]]だけのコンポーネントの場合、 constructor(props,context){ super(props,context) } >constructorの記述自体を丸々省略できる。 ***render [#w9dbdb36] -生成したいHTML(正確には[[JSX>#ne8ad84a]])を書く。 -return( の直下は1つのエレメントしか置けない。 -繰り返し処理~ map内にラムダ式を書く。 --配列 items = [ { value : 'apple' }, { value : 'orange' }, { value : 'banana' }, ]; --値 return items.map(_item => { return( <li>{_item.value}</li> ) }) --キー、値 return items.map((_item,_key) => { return( <li key={_key}>{_item.value}</li> ) }) -コンポーネントの再描画 --[[state>#j6338a61]]を更新して、コンポーネントを再描画する。 --イベントなどで、上記のthis.stateを変更するとHTMLが再描画される。 class MyComponent extends React.Component { constructor(props, context) { super(props, context) this.state = { viewText: props.text, viewFlg: props.defaultFlg, } } renderChange() { // viewFlgの状態を切替(0 <-> 1) let newFlg = this.state.viewFlg == 1 ? 0 : 1; this.setState({ viewFlg: newFlg }); } render() { return ( <div> <h1>Hello! World.</h1> <LeadText viewText={this.state.viewText} viewFlg={this.state.viewFlg} /> <button onClick={()=>this.renderChange()}>切替</button> </div> ) } } **その他のコンポーネント [#c0057ae7] ***状態を持たないコンポーネント [#j9387807] Stateless functional components [[state>#j6338a61]]を自身で持たないシンプルなコンポーネントの場合、~ React.Componentを継承したクラスの定義は不要。 -定義 --[[props>#wac86e94]]がない場合 ---匿名関数 const Hello = function() { return <div>Hello XXXX</div> } ---ラムダ式 const Hello = () => <div>Hello XXXX</div> ---使い方 <Hello /> --[[props>#wac86e94]]がある場合 ---匿名関数 const Hello = function(name) { return <div>Hello name</div> } ---定義~ 関数の引数でDestructuring const Hello = ({name}) => <div>Hello {name}</div> ---使い方 <Hello name="XXXX" /> ***テンプレート・コンポーネント [#u0271a61] -定義~ {this.props.children}で子を描画。 // テンプレート・コンポーネント class TemplateComponent extends React.Component { render() { return ( <main> <header> <h2>{this.props.title}</h2> </header> <div> {this.props.children} </div> <footer> <p>copyright company</p> </footer> </main> ) } } -利用~ TemplateComponentにChildComponentを指定。 // Mainコンポーネント class MainComponent extends React.Component { render() { return ( <section> <h1>Main Title</h1> <TemplateComponent title={'コンテンツタイトル'}> <ChildComponent /> </TemplateComponent> </section> ) } } **コンポーネントの属性 [#sbf92665] ***refs [#t4a0cd56] 同一コンポーネントのインスタンスを識別する。 *データおよびイベント連携 [#n8b8bac0] **親から子 [#dfd6902c] ***[[props>#wac86e94]] [#dea212dc] -基本 --子側で(利用を)定義 this.props.XXXX --親側でデータを指定。 <子 XXXX={JavaScriptの値}> -型指定と既定値 --[[基本形のコンポーネント>#z184f699]]~ ・・・ --[[Stateless functional components>#j9387807]] Hello.propTypes = { name: React.PropTypes.string } Hello.defaultProps = { name: 'XXX' } ***JSX Spread Attributes [#o23213b7] 親コンポーネントが保持しているデータを~ 全て子コンポーネントの[[props>#wac86e94]]に渡す。 -子側の定義は不要で、以下のように利用可能。 -親側でスプレッド演算子によりデータを指定。 --任意のデータ var props = {}; props.foo = x; props.bar = y; var component = <子 {...props} />; --親側のpropsデータ <子 {...this.props}> ***componentWillReceiveProps [#b6de5462] -親側は、 --this.stateをpropsにバインドしておき、 --setStateで変更を反映する。 -子側は、 --コンポーネントが新しい[[props>#dea212dc]]を受け取ると、 componentWillReceiveProps が変更通知として実行される。 --[[props>#dea212dc]]の更新をsetStateで反映する。 componentWillReceiveProps(newProps) { //JSON.stringify(newProps); this.setState({count: newProps.count}); } -参考 --ざっくり React チュートリアル~ https://qiita.com/pullphone/items/efcaee59cf2a5725c61d --javascript - Updating state with props on React child component - Stack Overflow~ https://stackoverflow.com/questions/39154967/updating-state-with-props-on-react-child-component **子から親 [#ubca9a39] -親のハンドラをthis.propsで子に渡して、 -子からハンドラを呼び出す(引数指定可能)。 -必要に応じて、「[[親から子>#dfd6902c]]」を行う。 -参考 --Reactでイベントの伝播 - yugr’s diary~ http://yugr.hatenablog.com/entry/2017/11/22/132059 *コンポーネント・ライブラリ [#k04fc76a] **CSS [#lfebe228] ***react-bootstrap [#va73ad58] -BootstrapをReactから使いやすくしたライブラリ。 -インストールと、CSS自体の読み込みが必要。 -参考 --react-bootstrapで書くとコンポーネント的にBootstrapが使えるよ! | 酒と涙とRubyとRailsと~ https://morizyun.github.io/javascript/react-js-bootstrap-javascript-css-framework.html ***Material-UI [#vf8e9959] -[[マテリアルデザイン>https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%86%E3%83%AA%E3%82%A2%E3%83%AB%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3]]をReact.jsで実現するライブラリ。 -Bootstrapと提供機能はほとんど同じ。 npm install material-ui --save **拡張機能 [#y91afda7] ***react-hot-loader(AppContainer) [#uf49a267] Reactコンポーネントが状態を失うことなく、~ ライブで再ロードされるようにするプラグイン。 ***react-router-dom(BrowserRouter) [#lb25a2fc] https://reacttraining.com/react-router/~ https://reacttraining.com/react-router/web/guides/philosophy -Router --BrowserRouter~ 通常のRouter --HashRouter~ URLフラグメント、URLハッシュ値を使用したRouter -パラメタ --パラメタを持たないコンポーネント <Route exact path="/" component={FormInput}/> --パラメタを持つコンポーネント ---オブジェクト <Route exact path="/" render={props => <FormInput data={this.state.data} />} /> <p>Data:{ this.state.data }</p> ---URL <Route path="/:id" component={FormInput}/> <p>ID:{props.match.params.id}</p> -タグ --Link --Redirect ***isomorphic-fetch(fetch) [#q7ff35d6] XMLHttpRequest代替のfetch APIのPolyfill(WHATWG Fetch polyfill)。 -Fetch API - Web API インターフェイス | MDN~ https://developer.mozilla.org/ja/docs/Web/API/Fetch_API **データ連携 [#zfb27b06] ***[[Flux]] [#s9dbd4f8] ***[[Redux]] [#f382342b] **リサイズ・移動など [#y7cd5e1e] ***React-Resizable [#z0639cdb] Drag&Dropで画面項目をリサイズ ***React-Draggable [#w31b0555] Drag&Dropで画面項目を移動 **UIコンポーネント [#rfb0d19a] ***React Contextmenu [#u14123db] 右クリックでメニューを表示する ***React Tree Menu Component [#kcb92783] ツリーメニュー ***rc-calendar [#u805d6e9] カレンダーでの日付表示、日付入力機能 ***react-big-calendar [#g2a3e4d9] スケジューラ用途のカレンダー ***React Bootstrap Table [#s62d970a] 高機能テーブルコンポーネント(ソートやフィルタリング、ページジング)。 *[[React の step by step 的な]] [#q22025df] *参考 [#i144c1a1] **@IT [#cb9f8a95] -いまさら聞けないReact、Virtual DOM、JSX超入門 (1/3)~ http://www.atmarkit.co.jp/ait/articles/1607/26/news138.html **Qiita [#sd8946f9] -reactjsに関するxxxx件の投稿~ https://qiita.com/tags/reactjs -Destructuring assignmentのご利用は計画的に~ https://qiita.com/okunokentaro/items/ec3210a1942471fba612 -react-router@v4を使ってみよう:シンプルなtutorial~ https://qiita.com/hoture/items/b4ca1773580317e7112e -jsFiddleを使ってみる~ https://qiita.com/kazusa-qooq/items/f78791c827ae050ca127 **Schoo [#ybde9b1d] 学べる生放送コミュニケーションサービス -React.js入門~ https://schoo.jp/class/3437 -React.js実践入門~ https://schoo.jp/class/3628 **POSTD [#u16bf14e] -生のReactを知ろう – JSX、Flux、ES6、Webpackを使わず…~ https://postd.cc/learn-raw-react-no-jsx-flux-es6-webpack/ -大規模Reactアプリケーションを構築するためのベストプラクティス~ https://postd.cc/best-practices-for-building-large-react-applications/ -Web開発の未来 – React、FalcorおよびES6~ https://postd.cc/future-of-the-web-react-falcor/ **データ連携 [#f04c9975] ***State と Props [#f279343c] -React 0.13 日本語リファレンス | js STUDIO --propsの受け渡し~ http://js.studio-kingdom.com/react/guides/transferring_props --JSXのスプレッド属性~ http://js.studio-kingdom.com/react/guides/jsx_spread --componentWillReceiveProps~ http://js.studio-kingdom.com/react/component_lifecycle/updating_componentwillreceiveprops -Qiita --React における State と Props の違い~ https://qiita.com/kyrieleison/items/78b3295ff3f37969ab50 --今からはじめるReact.js〜propsとstate、それからrefs〜~ https://qiita.com/kuniken/items/a22adda392ccc30011b1 ***Flux [#v7718b51] -FacebookのFluxアーキテクチャの始め方 --Part 1~ https://postd.cc/introduction-to-facebooks-flux-architecture-1/ --Part 2~ https://postd.cc/introduction-to-facebooks-flux-architecture2/ -さらに多くのことが変化する – Fluxは新しい”WndProc”である~ https://postd.cc/the-more-things-change/ -Reactを用いたアプリケーションアーキテクチャ:Fluxを再考する~ https://postd.cc/application-architecture-with-react-rethinking-flux/ ***Redux [#g12d979f] -モバイル上のJSフレームワークの実行可能性 – ReactとRedux~ https://postd.cc/viability-of-js-frameworks-on-mobile/ **コンポーネント [#w6746f0f] ***Stateless Functional Components [#gfe894b2] -Qiita --ReactのStateless Functional Componentsの書き方~ https://qiita.com/ledsun/items/c577e004561b59f9a7e5 ***コンポーネント・ライフサイクル [#x5bcf220] -Qiita --React.jsのComponent Lifecycle~ https://qiita.com/koba04/items/66e9c5be8f2e31f28461 --React Componentのライフサイクルのまとめと利用用途~ https://qiita.com/yukika/items/1859743921a10d7e3e6b --React コンポーネント作成時に非同期通信したいときは componentDidMount に書こう~ https://qiita.com/megane42/items/213e927a2af72530e920 **Css in JS [#a4b204cc] -Qiita --React.js + CSS~ https://qiita.com/koba04/items/0e81a04262e1158dbbe4 -Styling and CSS - React~ https://reactjs.org/docs/faq-styling.html#what-is-css-in-js **マイクロソフト系技術情報 Wiki [#yd21a2a3] -ASP.NET Core SPAテンプレート~ https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Core%20SPA%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88 --ASP.NET Core React.jsテンプレート~ https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Core%20React.js%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88 --ASP.NET Core React+Reduxテンプレート~ https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Core%20React%2BRedux%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88