【React】面白いhooksを作ったよ!【全員が同じstateを共有する】
useStateってありますよね
const [state, setState] = useState({count:0, boolean:true})
const [state, setState] = useState({count:0, boolean:true})
Reactで最もよく使う状態管理を行うhook、 useState
。めちゃくちゃ使い心地いいですよね。
でもこのuseState
は、当たり前ですが、共有されません。 沖縄県在住のAさんがsetState
で状態を変更しても、東京都在住のBさんのstate
には影響を与えません。 当たり前ですね。
でもそれができたら面白くない?
誰かがsetState
を実行したら、それが同じページを見ているすべての人に反映されたら何か面白いことができそうじゃないですか?
例えば、オンライン勉強会とかができる
上記のデモ画面を見てください。ブラウザを二つ立ち上げて、片方だけを操作しています。なのに、もう片方のスライドも同期してスライドが切り替わっているのが分かるでしょうか。
これはスライド番号をstate
として持っておいて、setState
でスライド番号を切り替えると、同じURLを見ている人全員のstate
を切り替えることができています。
これによって、みんなが同じスライドを見ている状態を作ることができているので、Webで完結するオンライン勉強会ができそうな雰囲気が出てきましたよね(ワクワク)。
どうやって使うの?
筆者が開発中のRealtimely(ベータ版※)を利用することですぐに試すことができます。
使い方は至ってシンプルで、ほとんどReactのuseState
と同じような使い心地にしています。
以下サンプルコードを見てください。
useRealtimeSharedState
というhook関数がrealtimelyにあるので、useState
のように宣言してあげています。一つだけ違うのは、useRealtimeSharedState
の第二引数に識別子の文字列を入れてあげるだけ。これは同じURL内で複数の共通stateを持ちたい時に別の識別子を指定して区別できるようにする必要があるからです。
ボタンを押すとsetSharedState
で状態が切り替わるような実装をしてあげれば、同じURLを見ている人すべてのsharedState
が切り替わるようになります。
import React from "react";
import { useRealtimeSharedState } from 'realtimely';
const Home = () => {
const [sharedState, setSharedState] = useRealtimeSharedState({ count: 1, boolean: true }, "realtime-state")
const onClickButtonA = () => {
setSharedState({ ...sharedState, count: sharedState.count + 1 })
}
const onClickButtonB = () => {
setSharedState({ ...sharedState, boolean: !sharedState.boolean })
}
return (
<div>
<main>
<button onClick={onClickButtonA}>{"setSharedState({...sharedState, count: sharedState.count+1})"}</button>
<button onClick={onClickButtonB}>{"setSharedState({ ...sharedState, boolean: !sharedState.boolean })"}</button>
<h1>
{JSON.stringify(sharedState)}
</h1>
<h3>
And This state is shared by everyone looking at this URL
</h3>
</main>
</div>
)
}
export default Home
え?そんなの信じられないって?
デモページがあるから試してみてね。
どうやって動いてるの?
詳細はRealtimely docsに譲るとして、簡単に説明するとこうです。
「URL + 識別子」を一意のキーにしたデータベースを作り、setSharedState
が実行されたらそこに最新のsharedState
を送信する。
同じURLを見ている人は常に「URL + 識別子」の値を監視しており、更新されたら最新の値をwebsocketで配信するようにする。
最新の値が配信されたら、ローカルのsharedState
を最新に置き換える。
これによって、上記のような仕組みが出来上がります!!
バックエンドを自分で作るにはどうする?
RealimelyはDynamoDBとAWS AppSyncを使って上記の仕組みを実装しています。
CloudFormationなどで配布したいのですが、そこまで手が回っていないのが現状です。
他にもFirebaseのFirestoreでも同様の実装ができるのではないかと思いますので、やりたい人は思い思いにやってみてください。
まとめ
同じURLを見ている人全員のstate
を同期できたら面白いことができそうじゃないかと思って仕組みを作ってみました。
この仕組みでこんなことができそう!みたいなアイディアがあったらコメント欄で教えてください!!!
※ 記事中で紹介したRealtimelyはベータ版であり、セキュアではありません。プロダクションで使用したい場合は自前で実装するか、Realtimelyの開発が進むように支援してください😄
Author And Source
この問題について(【React】面白いhooksを作ったよ!【全員が同じstateを共有する】), 我々は、より多くの情報をここで見つけました https://qiita.com/yuno_miyako/items/1ec4fd69004fe31ead86著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .