react-navigationでスクリーンの重なりを保持したまま深い階層に飛ぶ
小ネタ
良いタイトルが思いつかなかった
react-navigationでいっきにnavigate()で2つStack詰む方法あるのかな?バックボタン押した時に戻る分も設定したくて
— .あーる (@DotEarl) 2018年4月2日
プッシュ通知からのDeeplinkで特定の深い階層に飛ばしたい時、ただnavigateで飛ばすだけだとバックボタンで戻った時の階層が設定されない
— .あーる (@DotEarl) 2018年4月2日
navigation.navigate('ScreenC')
例えば、こうして直接Screen: C
のコメントページを開いただけだと
バックボタンを押した時にScreen: B
の記事ページが無くてTOPに戻ってしまう
直接Screen: C
に飛んだときでもバックボタンでScreen: B
に戻れるようにしたい
ちょっと調べてみたら簡単だった
navigation.navigate( 'ScreenC', { id: 1000 }, // params navigation.navigate('ScreenB') )
navigate
の第3引数にまたnavigate
を設定するとネストして指定できる
このナビゲーションを実行すると Screen: C
が開いて、バックを押すと Screen: B
に戻るようになる
もちろんもう一度戻れば Screen: A
のTOPにたどり着く
React context APIを触ってみた
元ネタ
React v16.3でcontext API
というものが入った
このAPIを使うとRedux
と同じようなデータフローを簡単につくれるらしい
記事中にわかりやすい説明があるので動かしてみた
環境構築
create-react-app
をベースに使う
$ npx create-react-app my-app
ちなみに npx
は、グローバルインストールして使うようなnpmコマンドを落とさず、その場限りで実行させられるお手軽なツール
普通に create-react-app my-app
やっても良い
この記事を書いてる現時点だと、Reactのバージョンがv16.2
なので手動でアップグレードする
$ yarn add react@16.3.0-alpha.1 react-dom@16.3.0-alpha.1
動かしてみる
わかりやすくApp.js
にまとめて書く
<Provider>
で渡したvalue
が、その内部で書いた<Consumer>
に渡ってくる感じ
import React, { createContext } from 'react' // context api const Context = createContext() const { Provider, Consumer } = Context class App extends React.Component { state = { count: 0 } render() { return ( <Provider value={{ // 共有したい値を渡す state: this.state, actions: { increment: () => this.setState({ count: this.state.count + 1 }), decrement: () => this.setState({ count: this.state.count - 1 }) } }} > <Counter /> </Provider> ) } } const Counter = () => ( <Consumer> {({ state, actions }) => ( // Providerで渡したvalueがそのまま返ってくる <div> <span>{state.count}</span> <button onClick={actions.increment}>+1</button> <button onClick={actions.decrement}>-1</button> </div> )} </Consumer> ) export default App // index.js // ReactDOM.render(<App />, document.getElementById('root'));
動いた
https://rskull-sandbox.github.io/react-context-api/
react-stateful
context APIをラップして、よりReduxっぽい仕組みを取り入れたのがreact-stateful
ソースみたら1ファイルで100行も無かった
すごいシンプルなものなら楽に作れそう
GoogleHomeとIoTデバイスでオフィスのQOLを上げた話
GoogleHomeとIoTデバイスを使ってオフィス環境の向上と
仕事が効率化するように色々やったので紹介しようと思います
前提として、うちの会社(Togetter社)はオフィスに10名ちょっとしかいないので、GoogleHomeに好き勝手喋らせてもわりと大丈夫です
プログラム郡はすべてラズパイ上で動かしています
永続化はforever
API経由でGoogleHomeに好きな言葉を喋らせる
記事を探せばたくさん出てくるこのライブラリを使う
const googlehome = require('google-home-notifier') googlehome.device('Google-Home', 'ja') googlehome.notify('こんにちは', () => {})
これだけで喋ります
汎用的にするために、用意したAPIにワードをPOSTすると喋ってくれるようにしてみます
基本的な手順は前に書いた記事とほぼ同じなので、ざっと説明します。詳しくは下のリンクを見て下さい。
1. Fireabseの設定
Firebaseのデータベースを設定します
こんな感じの構造にします
2. Firebaseの更新を監視するコードを書く
const firebase = require('firebase'); const googlehome = require('google-home-notifier') googlehome.device('Google-Home', 'ja') // firebase const config = { apiKey: "xxxxxxxxx", authDomain: "xxxx.firebaseapp.com", databaseURL: "https://xxxx.firebaseio.com", projectId: "xxxx", storageBucket: "xxxx.appspot.com", messagingSenderId: "01234567" } firebase.initializeApp(config) const db = firebase.database(); const ref = db.ref('/googlehome'); ref.on('value', function(changedSnapshot) { const key = changedSnapshot.key; const text = changedSnapshot.child('text').val(); if (text !== '') { // GoogleHomeに喋らせる googlehome.notify(text, () => {}) ref.set({ text: '' }) } })
これでデータベースのtext
カラムが更新されると、そのテキストを喋ってくれるようになりました
3. IFTTTを設定
New Appletを押して
if Webhook
then Webhook
な設定をします
最初のWebhook
のトリガーは1つしかないので、そのままそれを選択します
Event Nameはなんでも良いので、適当なものを設定してください
次にthenのWebhook
では、APIからきたリクエストをFirebaseに書き込む設定をします
保存して適用しましょう
下記のページにアクセスして、Documentation
と書いてあるページに飛ぶと
エントリーポイントとなるURLが確認できます
$ curl -X POST -H "Content-Type: application/json" -d '{"value1": "こんにちは"}' \ https://maker.ifttt.com/trigger/googlehome/with/key/xxxxxxxxxxxx
curlでテストすると喋ってくれるようになしました
好きなことを喋らせられる機能
これは実験的ですが、上で作ったAPIを叩くフォームを作りました
Firebaseに書き込めばなんでも喋るので直接書き込んでもいいですが、出来るだけ楽をしたかったのでこうしました
もちろん社内からしかアクセスできません
公開したらみんな変なこと喋らせるのですぐ閉じました :(
カレンダーのスケジュールをアナウンスさせる
IFTTTを使って設定しました
if GoogleCalender
then Webhook
トリガーにGoogleCalenderのAny event starts
を選択
このトリガーはスケジュールのn分前(任意の設定)になると発火するので、その後に
Webhook
でFirebaseのgooglehomeに書き込むようにすれば、予定をアナウンスしてくれるようになります
ゴミ当番を指名してアナウンス
小さいオフィスなので、ゴミ捨ては自分たちでやります
人がいたりいなかったりして当番制もやりにくいので抽選するプログラムを書きました
弊社ではとある勤怠管理Webサービスを使っていて、そこのAPIから出勤してる人一覧を取れます
なので、単純に出勤してる人の中から1名をランダムで抽出して喋らせるバッチを書いて
それをcronでゴミの日に実行されるようにすることで
「今日のゴミ当番は○○さんです。よろしくお願いします」とアナウンスさせることが出来るようになります
機会に言わせることで無駄な争いを生むこともありません。素敵ですね!
室内環境を監視してアラートさせる
去年、弊社では室内の二酸化炭素濃度を計測するモニターを買って、濃度が高くなったら換気をするという習慣をつけるようにしました
※ 弊社社長の去年のツイート
オフィスの二酸化炭素濃度を監視してる。かなり換気しないと快適にならないことが判明した。快適オフィスへの道は厳しい。 pic.twitter.com/w91k8Fvp20
— yositosi (@yositosi) 2017年8月4日
二酸化炭素濃度はppm
という単位で表されます。
室内の最適なppm値はだいたい400 ~ 800くらいです。1000ppmがギリギリで、それ以上になってくると
頭がぼーっとしてきたり、息苦しくなってきます。
このモニターを使って毎日室内のCo2濃度を監視していたのですが、濃度が高くなったらGoogleHomeに警告させたいよね!
となったので、探してみたらAwair
というIoTデバイスを発見しました
日本サポートもあり、技適も通ってるので大丈夫そうです
Awairは温度・湿度・Co2濃度・化学物質・ホコリを警告してくれる高性能なデバイスです
化学物質ってなんだ?と思っていましたが、シンナー臭い除光液とか使ってると反応して数値が高くなります(体験談
GoogleHomeと同じで、スマホにアプリを入れて連帯することで本体の設定や数値の確認をすることが出来ます
IFTTTに対応していて、各項目の数値が高くなったりしたときにトリガーすることが出来るので
さっきと同じようにWebhook
でFirebase
に投げてGoogleHomeにアナウンスさせるようにしました
社内のGoogleHomeが @DotEarl によって毎日進化していて、会社の予定を教えてくれたりしてたのだが、今日ついに「二酸化炭素が多いから窓開けてください」って命令されるようになった。
— yositosi (@yositosi) 2018年2月21日
こうして人間はAIに管理され、何も考えなくても良くなってくる。 pic.twitter.com/Y07Uk1NCYU
デモ
AwairとGoogleHome連携させたやつ
— .あーる@素振り (@DotEarl) 2018年2月21日
二酸化炭素濃度が基準値超えると警告してくれるようにした pic.twitter.com/XhY1D5S6CR
これにより、弊社のオフィス内は温度・湿度・Co2濃度・化学物質・ホコリともに出来るだけ最高の状態を保つようにしています!
加湿機も3台フル稼働していて、なかなか忙しない感じです
室内環境で、とくに空調は体にダイレクトに影響するので
これらのデバイスを組み合わせてどんどん機会に支配されていきましょう!
終わりです。
今更だけどparcelの素振り
parcel + react + reduxを動かしてみる
環境構築
セットアップの仕方は公式サイトに親切に書いてある
parcelをグローバルインストール
$ yarn global add parcel-bundler
ディレクトリを作成
$ mkdir parcel & cd parcel $ yarn init -y
まずはドキュメント通り、react + parcelだけの必要最小限のパッケージをインストールする
$ yarn add react react-dom $ yarn add --dev parcel-bundler babel-preset-env babel-preset-react
.babelrc
{ "presets": ["env", "react"] }
コードを書く
index.html
<html> <body> <div id="app"></div> <script src="./index.js"></script> </body> </html>
index.js
import React from 'react' import ReactDOM from 'react-dom' class Hello extends React.Component { render() { return <div>hello world</div> } } const app = document.getElementById('app') ReactDOM.render(<Hello />, app)
実行
$ parcel index.html
エラーなく立ち上がれば http://localhost:1234
で繋がるようになる
アクセスしてブラウザにhello world
が表示されていれば成功
reactもちゃんと動いてる
ビルド後のソースは dist
フォルダに生成される
dist ├── index.html ├── parcel.js └── parcel.map
reduxを導入する
$ yarn add redux react-redux
最小限だとこれだけで動く
前書いた記事のreduxの最小限の構成を輸入したら
問題なく動いてたので成功した
https://github.com/rskull/parcel-react
感想
簡単
素振りおそすぎた
追記 (2018/02/14)
本番ビルドだと動かなかった
メソッドがないよってエラーが出る
なぜ