最近 React Native を触り始めて 〜ListView ハマりポイント〜

46a83308107e50135d9beee5f30c8aa1?s=47 diskshima
November 04, 2016

最近 React Native を触り始めて 〜ListView ハマりポイント〜

2016/11/04 の「React&React Native入門者の会」のLTのプレゼン資料です。
React Native の ListView でハマるポイントを1つ紹介しています。

46a83308107e50135d9beee5f30c8aa1?s=128

diskshima

November 04, 2016
Tweet

Transcript

  1. 最近 React Native を触り始めて 島本 大輔 @diskshima 〜 ListView のハマりポイント〜

  2. 自己紹介 名前: 勤務: 仕事: 島本 大輔 @diskshima インテグリティ・ヘルスケア株式会社 (医療系スタートアップ) React

    Native で iOS アプリ&Ruby でサーバ開発
  3. モバイルのアプリと言えば

  4. そう、リストですね

  5. React Native でリストといえば

  6. React Native でリストと言えば ListView https://facebook.github.io/react-native/docs/listview.html

  7. ListView あるある 今回は ListView あるあるを1件紹介しようと思います。 多分、みんな1回はハマるんじゃないかなー、と思います。

  8. ListView あるある 簡単なサンプルアプリを作りました。 this.data = [ new Player('Eric Cantona'), new

    Player('David Beckham'), new Player('Ryan Giggs'), new Player('Gary Neville'), ]; const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.state = { dataSource: ds.cloneWithRows(this.data) }; データを読み込む部分はこんな感じです。
  9. ListView あるある 「Add Ronaldo」 ボタンを押した時のコード onButtonPress() { const newPlayer =

    new Player('Cristiano Ronaldo'); this.data.push(newPlayer); } this.data は ListViewDataSource に追加済みだから、動く でしょ。
  10. ListView あるある 押してみる ここに出てきてほしい

  11. ListView あるある 反映されない (T T)

  12. ドキュメントを読む ListView のデータを保持するのは ListViewDataSource。 https://facebook.github.io/react-native/docs/listviewdatasource.html

  13. ドキュメントを読む https://facebook.github.io/react-native/docs/listviewdatasource.html ここっぽい!

  14. ドキュメントを読む To update the data in the datasource, use cloneWithRows

    (or cloneWithRowsAndSections if you care about sections). The data in the data source is immutable, so you can't modify it directly. The clone methods suck in the new data and compute a diff for each row so ListView knows whether to re-render it or not.
  15. ドキュメントを読む To update the data in the datasource, use cloneWithRows

    (or cloneWithRowsAndSections if you care about sections). The data in the data source is immutable, so you can't modify it directly. The clone methods suck in the new data and compute a diff for each row so ListView knows whether to re-render it or not. datasource を更新するときは cloneWithRows か cloneWithRowsAndSections を呼んでね。 datasource の中にあるデータは変えられないけど、この clone メソッドでデータを読み取って、差分を計算の 上、再描画するかどうか決めます。 訳した
  16. とりあえず呼んでみる ボタンハンドラを変えて呼んでみる。 onButtonPress() { const newPlayer = new Player('Christiano Ronaldo');

    this.data.push(newPlayer); // ↓↓↓ 追加 ↓↓↓ this.setState({ dataSource: this.state.dataSource.cloneWithRows(this.data) }); }
  17. とりあえず呼んでみる もう一回、押してみる…

  18. とりあえず呼んでみる ちゃんと加わった!

  19. どういうこと? ソースを読んでみる。 https://github.com/facebook/react-native/blob/0.36-stable/Libraries/CustomCompo nents/ListView/ListViewDataSource.js

  20. ソースの旅(長いから詳細は割愛) • dirty って名前があったのは _calculateDirtyArray(dirty チェック) ◦ dirty = 変更があったかのチェック

    ◦ rowHasChanged もこのメソッドのみ ▪ ListViewDataSource.js#L383 らへん • _calculateDirtyArray を呼んでいるのは cloneWithRowsAndSections だけ • cloneWithRows は cloneWithRowsAndSections の薄いラッパー
  21. 要は 変更を拾ってもらうには • cloneWithRows • cloneWithRowsAndSections のどちらかを呼ばないといけない。

  22. clone?遅くないの?

  23. clone?遅くないの? 渡している配列を全部コピーするのではなく、ListViewDataSource を新しく作って (clone)、配列を中に設定しているだけ。 結構気楽に呼びまくっても良いみたいです。

  24. clone?遅くないの? 渡している配列を全部コピーするのではなく、ListViewDataSource を新しく作って (clone)、配列を中に設定しているだけ。 結構気楽に呼びまくっても良いみたいです。 というか、他に選択肢ない…

  25. 結論 ListView のデータを更新したときは とりあえず cloneWithRows / cloneWithRowsAndSections を呼びましょう。

  26. ご静聴ありがとうございました。