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

その後、標準を作成できます index.html を含むページ app.js これには私たちが含まれます hyperapp コード。

<!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
}

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

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

最後に、これをDOM内の特定の要素にアタッチできます。 私はこれをに追加することを選択しました div とともに idapp:

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) })
};

これは私たちの内部に配線することができます mainview 私たちへのアクセスを与えるために 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 を取り込むカウンターを追加します count から props:

Count.js
import { h } from 'hyperapp';

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

export default Count;

その後、 import この中 app.js:

app.js
import Count from './components/Count';

// ...

次に、合格することができます count 私たちの小道具として Count 以内 view:

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

私も更新しました stateactions シンプルに incrementdecrementcount:

const state = {
  count: 0
};

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

ルーティング

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

$ npm i @hyperapp/router

その後、 import 内部のルーティングコンポーネント app.js:

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

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

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>;

The 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>
);

次に、ルーターにアクセスを許可する必要があります location、HistoryAPIに基づいているため。 以下を追加してください 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にも注目してください。まもなくリリースされる予定です。