Hyperappの簡単な紹介

提供:Dev Guides
移動先:案内検索

Hyperapp は、宣言型Webアプリケーションの構築に使用される非常に小さいマイクロフレームワークです。 サイズはわずか1kBで、APIはReactに似ていますが、完璧ですよね?! Hyperappがどのように機能するかを示すために、小さなカウンターアプリを作成します。

新しいハイパープロジェクト

開始するには、新しいノードアプリケーションを作成し、hyperappをインストールします。 次に、parcelを使用してこのアプリケーションを提供します。

# New directory, here we call it `hyper`
$ mkdir hyper && cd hyper

# Initialise Node project
$ npm init -y

# Install Hyperapp
$ npm i hyperapp

# Create index.html and app.js
$ touch index.html
$ touch app.js

# Install `parcel` globally
$ npm i parcel -g

# Serve our application in the browser
$ parcel index.html

次に、hyperappコードを含むapp.jsを含む標準のindex.htmlページを作成できます。

<!DOCTYPE html>
<html lang="en">
<head>
  <title>🎉 Hyperapp</title>
</head>
<body>
  <div id="app"></div>
  <script src="app.js"></script>
</body>
</html>

カウンターの構築

状態駆動型アプリケーションは、常に反例から始まります。 これにより、アプリケーション内でのデータの流れに慣れることができます。 いくつかのstateを定義することから始めましょう:

app.js

const state = {
  count: 0
}

次に、そのstateに基づいてviewを定義できます。 これは、標準のテンプレート構文を使用して表示できます。

app.js

// ...
const view = state => (
  <div>
    <h1>{state.count}</h1>
  </div>
);

最後に、これをDOM内の特定の要素にアタッチできます。 appidを使用して、これをdivに追加することを選択しました。

app.js

// ...
const el = document.getElementById('app');

const main = app(state, {}, view, el);

シンプルなアプリは次のようになります。



stateは不変であり、直接更新する必要がないため、actionsを追加して、stateを次のように操作できます。

app.js

// ...
const actions = {
  increment: () => state => ({ count: (state.count += 1) }),
  decrement: () => state => ({ count: (state.count -= 1) })
};

これは、mainおよびviewの内部に配線して、actionsにアクセスできるようにすることができます。

app.js

// ...
const view = (state, actions) => (
  <div>
    <h1>{state.count}</h1>
    <button onclick={() => actions.increment()}>Increment</button>
    <button onclick={() => actions.decrement()}>Decrement</button>
  </div>
);

const main = app(state, actions, view, el);

ここで、[インクリメント]または[デクリメント]を選択すると、合計カウントが増減します。



これを特定の数だけ上下させたい場合はどうなりますか? この機能を追加しましょう。

まず、stateオブジェクトに新しいアイテムを追加できます。 これをdiffと呼ぶことにしました。これは、加算と減算の違いを表すためです。

const state = {
  count: 1,
  diff: 1
};

次に、actionsを更新して、これに基づいてインクリメントまたはデクリメントできます。

const actions = {
  updateCount: diff => state => ({ diff: diff }),
  increment: diff => state => ({ count: (state.count += Number(diff)) }),
  decrement: diff => state => ({ count: (state.count -= Number(diff)) })
};

そして最後に、viewを更新できます。

const view = (state, actions) => (
  <div>
    <input value={state.diff} oninput={e => actions.updateCount(e.target.value)} />

    <h1>{state.count}</h1>
    <button onclick={() => actions.increment(state.diff)}>Increment</button>
    <button onclick={() => actions.decrement(state.diff)}>Decrement</button>
  </div>
);

これで、入力データを利用して状態を更新できるようになりました。

コンポーネント

Hyperappプロジェクトからコンポーネントを作成する方法を見てみましょう。 Counterコンポーネントを作成し、これをページとルートの中に埋め込む方法を見ていきます。

components/Count.jsに新しいファイルを作成し、propsからcountを取り込むカウンターを追加します。

Count.js

import { h } from 'hyperapp';

const Count = ({ count }) => <h1>{count}</h1>;

export default Count;

次に、app.jsの内部でimportを実行できます。

app.js

import Count from './components/Count';

// ...

次に、countを小道具としてview内のCountに渡すことができます。

app.js

// ...
const view = () => (state, actions) => (
  <div>
    <Count count={state.count} />
    <button onclick={actions.increment}>Increment</button>
    <button onclick={actions.decrement}>Decrement</button>
  </div>
);

また、stateactionscountの単純なincrementdecrementに更新しました。

const state = {
  count: 0
};

const actions = {
  increment: () => ({ count: (state.count += 1) }),
  decrement: () => ({ count: (state.count -= 1) })
};

ルーティング

Hyperapp内のルーティングを利用することもできます。 次のようにルーターパッケージ(@hyperapp/router)をインストールしましょう。

$ npm i @hyperapp/router

次に、app.js内のルーティングコンポーネントをimportできます。

app.js

import { Link, Route, location } from '@hyperapp/router';

これで、HomeBlogの2つの異なるページを作成できます。

app.js

// ...
const Home = () => (state, actions) => (
  <div>
    <Count count={state.count} />
    <button onclick={actions.increment}>Increment</button>
    <button onclick={actions.decrement}>Decrement</button>
  </div>
);

const Blog = () => <h1>Blog!</h1>;

Homeページには以前の反例が含まれており、Blogページは単なるテキストです。 これらをRouteLinkとして、viewの内部に割り当てましょう。

app.js

// ...
const view = state => (
  <div>
    <ul>
      <li>
        <Link to="/">Home</Link>
      </li>
      <li>
        <Link to="/blog">Blog</Link>
      </li>
    </ul>

    <Route path="/" render={Home} />
    <Route path="/blog" render={Blog} />
  </div>
);

次に、History APIに基づいているため、ルーターにlocationへのアクセスを許可する必要があります。 stateactionsに以下を追加します。

app.js

const state = {
  location: location.state,
  count: 0
};

const actions = {
  location: location.actions,
  increment: () => state => ({ count: (state.count += 1) }),
  decrement: diff => state => ({ count: (state.count -= 1) })
};

最後に、location自体をサブスクライブする必要があります。

app.js

// ...
const unsubscribe = location.subscribe(main.location);

これで、アプリケーション内のさまざまなページから選択できるようになりました。



ルーティング例の完全なコードは次のとおりです。

app.js

import { h, app } from 'hyperapp';
import { Link, location } from '@hyperapp/router';

import Count from './components/Count';

const state = {
  location: location.state,
  count: 0
};

const actions = {
  location: location.actions,
  increment: () => state => ({ count: (state.count += 1) }),
  decrement: diff => state => ({ count: (state.count -= 1) })
};

const Home = () => (state, actions) => (
  <div>
    <Count count={state.count} />
    <button onclick={actions.increment}>Increment</button>
    <button onclick={actions.decrement}>Decrement</button>
  </div>
);

const Blog = () => <h1>Blog!</h1>;

const view = state => (
  <div>
    <ul>
      <li>
        <Link to="/">Home</Link>
      </li>
      <li>
        <Link to="/blog">Blog</Link>
      </li>
    </ul>

    <Route path="/" render={Home} />
    <Route path="/blog" render={Blog} />
  </div>
);

const main = app(state, actions, view, document.body);

const unsubscribe = location.subscribe(main.location);

結論

これで、あなたはレースに出かける必要があります! 🏇また、 Hyperapp2.0にも注目してください。まもなくリリースされる予定です。