Reactでobnizを使おう



Reactでobnizを使うにはちょっと一工夫いるっぽいので試してみました。

Reactで使うWebpackが、obnizで使っているwebpackを認識しなくて設定を引き継いでくれないようで、底の部分に関していくつか修正が必要なようです。



**とにかく結論だけ知りたいんだという方は、[こちらのgithub](https://github.com/9wick/obniz-react-sample)を参照ください。**


<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">reactを使ってリアルタイムでobnizをレンダリング <a href="https://t.co/B8RMTxFDWh">pic.twitter.com/B8RMTxFDWh</a></p>&mdash; kido (@9wick) <a href="https://twitter.com/9wick/status/1269097023216615424?ref_src=twsrc%5Etfw">June 6, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>





### dialog-polyfill が必要

obnizの内部ではdialog-polyfillを使っています。（nodejs版では不要ですが、HTML版にwebpackする際に必要）。

npm install で入れてしまいましょう

```
npm install -D dialog-polyfill
```


### リソース読み込みのためにcssやyamlファイルを読み込めるようにする

obniz.js内部ではcssファイルやyamlファイルを扱っています。
webpackのデフォルト設定ではこれらを読み込むことができないので、
コレを読めるようにします

```
npm i -D json-loader yaml-loader raw-loader
```

webpackの設定のrulesにも、jsonやyaml、cssが読めるように設定します。

```javascript:webpack.config.js

module.exports = {
  ...
  module: {
    rules: [{
      test: /\.jsx?$/,
      exclude: /(node_modules|bower_components)/,
      use: [{
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-react', '@babel/preset-env']
        }
      }]
    },
      {
        test: /\.(yml|yaml)$/,
        use: [
          {
            loader: require.resolve('json-loader'),
          },
          {
            loader: require.resolve('yaml-loader')
          },
        ],
      },
      {
        test: /\.(css)$/,
        use: 'raw-loader',
      },
    ]
  },
  ...
};

```



### .mapエラーを消したい・・・・がまだわからず
 
obnizは.mapファイルをgitに入れていないため、読み込もうとしてそんなの無いよエラーが大量に出ています。
このワーニングを消したい！　が解消法はわかってないです。
原因のわかっているワーニングなので、取りあえず動くし放置しましょう。
<img width="599" alt="スクリーンショット 2020-06-06 10.52.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/666f904a-124c-0150-cdba-01ab585de99d.png">




# obnizとreactで使うときのサンプル

ここまでの対策でobnizは無事に動くようになります。
どんなふうにobnizとreactを使うとよいかちょっと書いてみましょう。


### connectする前にはobniz.displayやobniz.switchなどのプロパティにアクセスできない


obniz.onconnectが呼ばれるまでは、obnizのプロパティは一部存在しなく、obniz.displayなどにアクセスすることはできません。

obnizにはconnectionStateというプロパティがあるので、コレを使って接続中かどうか判断します。

```javascript

 if(this.props.obniz.connectionState === "connected"){
      this.props.obniz.display.clear();
      this.props.obniz.display.print(text);
 }
```


### コールバック関数の設定タイミング

スイッチの入力などのコールバック関数の設定タイミングに注意する必要があります。

reactのDOMが作られる瞬間に、obnizがオンラインなのか未接続なのかは状況次第になります。
未接続の場合はonconnectが呼ばれた段階でコールバック関数を設定したいですが、接続済みの場合はその後onconnectが呼ばれることはないので、そこに設定しても動作しません。

そこで、ここでも接続状況教によって場合分けをする必要があります。

また、この際、`obniz.onconnect`を上書きすると、他のところで設定しているものが使えなくなるので、
１つしか登録できない`obniz.onconnect`ではなく、`obniz.on('connect', ()=>{ ... })`を使いましょう

※`obniz.on('connect', ()=>{ ... })`はいくつ登録しても、全部の関数が呼ばれます。

```javaScript
export default class ObnizSwitchState extends React.Component {
  constructor(props) {
    super();
    this.state = {switchState: "unknown"};

    if (props.obniz.connectionState === "connected") {
      this.setupObniz();
    } else {
      props.obniz.on('connect', () => {
        this.setupObniz();
      })
    }
  }

  setupObniz() {
    this.props.obniz.switch.onchange = (state) => {
      this.setState({switchState: state})
    }
  }

...

}

```


#　というわけでサンプル

こちらのgithubに上げています。
https://github.com/9wick/obniz-react-sample


obnizIDの設定だけ変えてもらえればこんな形でうごきます。
https://github.com/9wick/obniz-react-sample/blob/master/src/js/components/Layout.js#L9

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">reactを使ってリアルタイムでobnizをレンダリング <a href="https://t.co/B8RMTxFDWh">pic.twitter.com/B8RMTxFDWh</a></p>&mdash; kido (@9wick) <a href="https://twitter.com/9wick/status/1269097023216615424?ref_src=twsrc%5Etfw">June 6, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>