4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Riot.js で純粋なコンポーネント(riot.pure)を使用する

Last updated at Posted at 2020-01-07

riot.pure

Riot v4.8.0でriot.pureが追加されたので使ってみます。

コンポーネントのレンダリングを自分で制御したい場合に、riot.pure を使うことで Riot.js の内部ロジックをスキップすることができるようです。
内部ロジックがスキップされる為、HTMLとCSSは使えません。

基本動作

riot.pureを使ってmountupdateunmountのメソッドを含んだオブジェクトを返すモジュールを登録します。

pure.riot
<my-pure>
  <script>
  import { pure } from 'riot'

  export default pure(({ slots, attributes, props }) => {
    console.log(slots, attributes, props);
    return {
      el: null,
      mount(el, context) {
        this.el = el;
        console.log("mount", el, context);
        this.el.innerHTML = 'Hello There';
      },
      update(context) {
        console.log("update", context);
      },
      unmount(preserveRoot) {
        console.log("unmount", preserveRoot);
        this.el.parentNode.removeChild(this.el);
      }
    };
  });
  </script>
</my-pure>

pureで受け取れる内容は以下の3つ

  1. slots - コンポーネント内で見つかった slot リスト
  2. attributes - コンテキストからコンポーネントプロパティを推測するために評価可能なコンポーネントの属性式
  3. props - riot.component 呼び出しによってのみ設定できる初期コンポーネントユーザープロパティ

pureの対象となるエレメントはマウント時にしかもらえないため、this.elに保持しています。

pureコンポーネントの使用はこんな感じで。

app.riot
<my-app>
  <p>{ props.message }</p>
  <my-pure></my-pure>
  <input type="button" value="update" onclick="{ pre_update }">
  <input type="button" value="unmount" onclick="{ pre_unmount }">

  <script>
    import { unmount } from 'riot'

    export default {
      pre_update(e) {
        this.update();
      },

      pre_unmount(e) {
        unmount('my-pure');
      }
    }
  </script>
</my-app>
index.js
import { component,register } from 'riot'
import App from './app.riot'
import Pure from './pure.riot'

register('my-pure', Pure);

component(App)(document.getElementById('root'), {
  message: 'Hello World'
});

試してみる…がunmount時に反応しない? -> <追記あり v4.8.7で修正済み>

image.png

どうやら、unmountの動きとしてriot-componentを持っていないとunmountを呼び出してくれないようです。

・動作確認用
https://plnkr.co/edit/sPjH1JE9zeLPErMBysx8?p=preview

というわけで、初めてのプルリクとやらをしてみました。1発ミスったのは内緒。
https://github.com/riot/riot/pull/2801

修正内容はいたって簡単で、持っていないなら持たせればいいじゃない、の精神。

riot/src/core/component.js
  return createCoreAPIMethods(method => (...args) => {
    component[method](...args)
    args[0][IS_PURE_SYMBOL] = component // ここ追加
    return component
  })
riot/src/riot.js
export function unmount(selector, keepRootElement) {
  return $(selector).map(element => {
    if (element[DOM_COMPONENT_INSTANCE_PROPERTY]) {
      element[DOM_COMPONENT_INSTANCE_PROPERTY].unmount(keepRootElement)
    // ↓ ここ追加
    } else if (element[IS_PURE_SYMBOL]) {
      element[IS_PURE_SYMBOL].unmount(keepRootElement)
    }
    return element
  })
}

1/20 追記
プルリクは却下されてしまいました(さすがに修正内容が安直すぎた)が、Issueで修正してもらえました!
https://github.com/riot/riot/issues/2806

v4.8.7でunmountもRiot.jsから呼んでもらえるようになっています。

まとめ

これを使えば複数のコンポーネントで使いまわせる共通の処理とか書けそう。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?