React / Reduxを使用する難民のためのHyperapp

画像







reduxが大好き



Reduxのおかげで、すばらしい関数型プログラミングの世界への旅が始まりました。 そして、これは私が本番環境で試した最初の機能です。 DOMを使用して状態を保存し、jQueryで不確かに操作した時代は終わりました。







Reduxは、アプリケーションの状態(状態)を管理するためのツールです。これにより、アプリケーションをビューから完全に分離できます。 ビューは状態の派生物になり、状態を変更するためのインターフェースをユーザーに提供します。 ユーザーアクションは、状態を直接変更しません。 代わりに、それらはレデューサーになります。 これは、前の状態(状態)とアクション(アクション)に基づいて次の状態(状態)を生成する純粋な関数です。 データを更新するこのアプローチは、主にElmプログラミング言語アーキテクチャとFlux単方向データフローの概念に触発されました。 これは間違いなく、今日存在するものの不変の状態変更のための最も人気のあるJavaScriptライブラリです。 Reduxの作成者は、アプリケーションの状態管理という1つの問題を解決することに焦点を当てており、それをうまく実行しました。 Reduxは、さまざまなライブラリと連携してビューを表示するのに十分なモジュール式であることが判明しました。







Reactは、ビューに対して同様の焦点を絞ったアプローチを使用し、ブラウザーDOM、ネイティブモバイルアプリケーション、VR、その他のプラットフォームに接続できる効果的な仮想DOMを備えています。







信頼性が高く、機能的で簡単にデバッグできるWebアプリケーションを作成するには、ReactとReduxを使用できます。 確かに、react-reduxのような補助ライブラリと定型コードの束が必要になります。 または、 Hyperappを試すことができます。







Hyperappは、 Reduのようにビュー(ビュー)と仮想DOMの表示と組み合わせて、Redux / Elmのようにアプリケーション(状態)と不変性の状態制御を提供する単一のライブラリです。 Hyperappは、関数型プログラミングアプローチを使用してその状態を管理しますが、副作用の解決、非同期アクション、およびDOMの操作においてより柔軟です。 Hyperappは、Webアプリケーションを構築するための強力な抽象化を提供しますが、同時にネイティブAPIに完全にアクセスできるため、制限されません。







画像







コードは千語以上を言います



React + Reduxと同等のHyperappのシンプルなカウンターアプリ:







React / Redux vs Hyperapp







コードの番号付きブロックをそれぞれ調べて、何が何なのかを見てみましょう。







1.状態



Reduxでは、状態はどのタイプでもかまいませんが、シリアル化が容易なデータタイプを選択することを強くお勧めします。 開発者の大半は、空のオブジェクトをレデューサーの状態として使用します。







コードには反映されていませんが、 Redux.createStore



呼び出しは、オプションの引数として初期状態を受け入れます。 Hyperappでは、状態は常にオブジェクトです。 状態を初期化する2つの異なる方法の代わりに、ここに1つあります。







2.アクション



Reduxでは、アクション作成者はJavaScriptオブジェクトなどのアクションを返す関数です。 通常、アクション作成者は、 mapDispatchToProps



引数を使用して、自動または手動でbindActionCreators



を使用してReduxストアに接続します。 通常、アクションは、単一ファイルからの複数のエクスポートとして定義され、ES6モジュールを使用する場合import * as actions from "./actions"



使用して単一のネームスペースにプルされます。







Hyperapp-アクション作成者、レデューサー、およびbindActionCreators



必要bindActionCreators



ません。 アクションは、状態を不変に変更し、これに必要なすべてのデータを持つ純粋な関数です。







3.状態の変化



Reduxでは、リデューサーで状態の変化が発生します。これは純粋な関数であり、状態とアクションを取り、次の状態を返します。 アクションは、任意のレデューサーの状態を更新できます。

状態変更関数の形式は次のとおりです。







 (state, action) => nextState
      
      





Hyperappは、次のような状態関数を使用します。







 (action) => (state [, actions]) => nextState
      
      





コードには反映されませんが、 Hyperappは状態のマージを行います。 したがって、 Object.assign



または{... state, key: "value"}



代わりに、単にreturn: {key: "value"}



だけreturn: {key: "value"}



十分です。







4.表示



Reduxでは、ビューを状態とアクションの作成者に手動で接続する必要があります。 これを行うには、 ReactRedux.connect



高次(HOC) ReactRedux.connect



を使用する必要があります。このReactRedux.connect



、コンポーネントをラップしてReduxストアに接続します。 これが機能するためには、アプリケーションを<ReactRedux.Provider>



でラップする必要もあります。これにより、ストアに接続したいコンポーネントがストアを利用できるようになります。







Hyperappでは 、状態とアクションがビューに自動的に接続され、トップレベルのコンポーネントのみがそれらにアクセスできます。







スライス数



ReduxとHyperappは、ネストされた名前空間で状態を維持しますが、わずかに異なるアプローチを使用してこれを行います。 Hyperappでは、これはすぐに使用できますcombineReducers



、手動でcombineReducers



を使用する必要があります。







Reduxを使用したコード:







 const potatoReducer = (potatoState = initialPotatoes, action) => { switch (action.type) { case FRY: // ... } } const tomatoReducer = (tomatoState = initialTomatoes, action) => { switch (action.type) { case GRILL: // ... } } const rootReducer = combineReducers({ potato: potatoReducer, tomato: tomatoReducer }) // This would produce the following state object { potato: { // ...potatoes // and other state managed by the potatoReducer... }, tomato: { // ...tomatoes // and other state managed by the tomatoReducer... // maybe some nice sauce? } }
      
      





Hyperappを使用した同等のコード:







 const rootState = { potato: { // ...just potato things }, tomato: { // ...just tomato things // maybe some nice sauce? } } const rootActions = { potato: { // these actions receive only // the potato state slice and actions }, tomato: { // these actions receive only // the tomato state slice and actions } }
      
      





非同期アクション



非同期アクション(アシオン)を整理する例







 const actions = { upLater: value => (state, actions) => { setTimeout(actions.up, 1000, value) }, // Called one second after upLater up: value => state => ({ count: state.count + value }) }
      
      





効果



画像







 import { withEffects, http } from "hyperapp-effects" const state = { // ... } const actions = { foo: () => http("/data", "dataFetched"), dataFetched: data => { // data will have the JSON-decoded response from /data } } withEffects(app)(state, actions).foo()
      
      





独自の効果を追加できます。







ミドルウェア



アクション作成者の機能を拡張するため、Reduxはストア作成レベルでapplyMiddleware



を使用することをapplyMiddleware



しています。







Hyperappには、アクションとミドルウェアの手動構成が含まれます。







 // Manual composition hoa3(hoa2(hoa1(app)))(state, actions, view, document.body) // Or with a standard-issue compose function compose(hoa3, hoa2, hoa1)(app)(state, actions, view, document.body) // Compose plays nicely with using different HOAs per environment const hoas = NODE_ENV === "production" ? productionHoas : devHoas compose(...hoas)(app)(state, actions, view, document.body)
      
      





単純なミドルウェアの例はhyperapp-loggerです 。これは、アクションのいずれかが呼び出されたときにコンソールに情報を出力します。







画像







 logger(options)(app)(state, actions, view, document.body)
      
      





完了



Hyperappは、Reduxと同様にシンプルさを真剣に考えています。 複雑さをよりシンプルにすることが可能です。 Hyperappのソースコードは最大300行のコードで、質問があるとき、または問題が発生したときにデバッグするときに読むことができます。 ライブラリのサイズはわずか1.4 kBです。







私は機能的な故郷のReduxから逃げていますが、それが好きではないからではなく、隣人が私に引き起こすすべての痛みや苦しみのためです。 私と同じようにReduxが好きで、データ変換の単純な機能的世界と複雑な外部の命令的世界との間のより良いバランスを探しているなら、 Hyperappにチャンスを与えることをお勧めします。








All Articles