Hoodie&Reactを使用したオフライン優先アプリ。 パート1:ブラウザーデータベース

最新のWebでは、ネイティブモバイルアプリケーションの特権であった問題のいくつかを解決できます。 インターネットがない場合でも、すべての機能をダウンロードして維持するWebアプリケーション(Webサイト)を作成し、表示されると自動的にサーバーと同期します。 モバイルデバイスでは、このようなアプリケーションの場合、ショートカットを作成するだけで十分です。自律性の観点から、ネイティブアプリケーションの類似物を取得します。


Todoリストの見た目を書きますが、1つ違いがあります。「完了した」タスクは削除されず、リストの最後に転送され、他のタスクが解決されるとポップアップします。 このリストは、さまざまなスポーツ活動、エンターテインメント、食べ物などの反復的なものに使用すると便利です。 私の社会的に知られている知り合いの1人は、彼女の友人ゾーンの大勢の人々との接触を均等に維持するためにそれを使用しています。


結果がここ見られます 。 いくつかの変更を加え、タブを閉じ、インターネットをオフにして、サイトを再度開いてみてください。 開いて、すべての機能を保持していることがわかります。 別のデバイスにログインしてオフラインで変更を行うと、接続が復元されたときに直感的に予想される方法で変更が同期されます。


この機能を実装するために必要なコードが非常に少ないことに驚くでしょう。


パート0:環境のセットアップ


次のwebpack設定でテキストが詰まらないように、既製の設定でカブを作成しました。 クローンを作成してパート0に切り替えてください: git checkout part0 。 注意すべき重要なポイント:



サーバーを起動してみてください。 Webpackがhttp:// localhost:8000 /ですべての準備が整ったと言ったら、サイトの素晴らしいヘッダーが見えるはずです。


パート1:ブラウザーデータベース


アプリケーションがオフラインモードで機能するには、データをどこかに保存し、何らかの方法でデバイス間で同期する必要があります。 Pouchdbはこれに最適です。 ただし、彼女と直接連携するのではなく、承認可能なHoodieラッパーを使用します。 src/App.jsプラグインしましょう:


 import Hoodie from '@hoodie/client' const hoodie = new Hoodie() 

データベースへのドキュメントの追加


次に、ループ(個別のToDoリスト)を追加するコンポーネントを作成します。


AddLoop.js
 import React from 'react' import TextField from 'material-ui/TextField' import RaisedButton from 'material-ui/RaisedButton' export default class AddLoop extends React.Component { constructor(props) { super(props) this.state = { title: '' } } handleTitleChange = (e) => this.setState({title: e.target.value}) handleSubmit = (e) => { e.preventDefault() this.props.store.add({ type: 'loop', title: this.state.title }) this.setState({title: ''}) } render() { return ( <form onSubmit={this.handleSubmit}> <TextField hintText="New loop" value={this.state.title} onChange={this.handleTitleChange} style={{marginRight: '10px'}} /> <RaisedButton label="Add" type="submit" primary={true} /> </form> ); } } 

ここで一番下の行はthis.props.store.addです。 storehoodie.storeあり、 App.jsレンダリングするときにコンポーネントプロパティに渡す必要があります。


 render() { ... <AddLoop store={hoodie.store} /> 

データベースを読む


データベースに保存されているドキュメントを表示してみましょう。 App.jsloadLoopsメソッドを追加しloadLoops


  constructor(props) { super(props); this.state = { loops: [] }; this.loadLoops(); } loadLoops = () => { hoodie.store.findAll(doc => doc.type == 'loop') .then(loops => this.setState({loops})) } 

stateを初期化し、ドキュメントの読み込みを開始するコンストラクターが必要でした。 hoodie.store.findAll 、必要なドキュメントのフィルターを渡し、受け取ったドキュメントをstate単純に書き込むという約束を取得しstate


render()追加してrender()しましょう:


  {this.state.loops.map(loop => ( <Paper key={loop.id} zDepth={2} style={{maxWidth: 400, margin: '20px auto'}}> <h3 style={{padding: 15}}>{loop.title}</h3> </Paper> ))} 

追加されたループのリストが表示されます。 ただし、新しいものを追加する場合、ページがリロードされたときにのみリストに表示されます。 それを修正しましょう。


データベースの変更を購読する


このアイテムのコードはすべて、 App.jsに数行追加することで構成されます。


  componentDidMount() { hoodie.store.on('change', this.loadLoops); } 

ループを追加すると、それらは自動的にリストに表示されます。 さらに、データベースの変更方法に関係なく。 これは重要です -別のデバイスとの同期中に変更が発生した場合でも、コールバックは機能します。


反応する理由


データベースを操作するロジックから、豊富なブラウザテンプレートエンジンの中から反応が選ばれた理由が明らかになります。 データベースの各変更に応じて、状態全体をリロードします。 そして、反応の場所で私のお気に入りのvue.jsの場合、彼はdom全体を再レンダリングします。 そして、これは単に遅いだけではありません。フォームに記入しているときに、別のデバイスがデータベースの変更を開始すると想像してください。フォームが再描画され、変更が失われます。 一方、仮想domでの反応は、変更された詳細をきちんと再描画し、フォームのフォーカスにさえ到達しません。


終わり


今日は、ブラウザデータベースと対話する方法を学びました。 次の部分では、サーバーデータベースを構成し、承認を固定します。 私はあなたのコメント/訂正/願いに喜んでいます。 この部分のコードは、 https//github.com/imbolc/action-loopタグpart1の下にあります。



Source: https://habr.com/ru/post/J309166/


All Articles