質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

2508閲覧

チャットがちゃんと表示されない(react native)

yamady

総合スコア176

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

3クリップ

投稿2018/04/21 01:34

なんども本当にすみませんmm

こちらのご指摘をいただきまして、ようやくmessages自体を表示することはできているのですが、バグが生じておりまして、完全にできていません。。

エラー&困っていること

データベースに入っているデータは表示されたかと思ったのですが...

エラー内容

Warning: rendering invalid section, row: 0, 0 Warning: rendering invalid section, row: 0, 1 Warning: rendering invalid section, row: 0, 2 ・・・ ExceptionsManager.js:73 Warning: Encountered two children with the same key, `.1:$r_s1_undefined`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.

Fetchされている様子

2点ほどおかしい点があります。
・同じ内容のmessageデータしか表示できていない
・通常、データベースに入っている数の倍乗のデータが表示されている

setStateしているmessagesに問題があるのでしょうか・・・

ソースコード

JavaScript

1class Message extends React.Component { 2 static navigationOptions = ({ navigation }) => { 3 return { 4 headerTitle: `${navigation.state.params.room.user.name}`, 5 headerLeft: ( 6 <TouchableOpacity 7 onPress={()=> navigation.goBack()} 8 style={styles.headerIcon} 9 > 10 <Icon name='chevron-left' size={28} style={{color: '#fff'}}/> 11 </TouchableOpacity> 12 ), 13 headerStyle: { 14 backgroundColor: Theme.PRIMARY, 15 }, 16 headerTitleStyle: { 17 color: '#fff', 18 fontWeight: 'bold' 19 } 20 }; 21 }; 22 23 constructor(props) { 24 super(props); 25 this.state = { 26 messages: [], 27 }; 28 } 29 30 componentWillMount() { 31 const room = this.props.navigation.state.params.room; 32 this.props.messagesFetch(room); 33 34 this.createDataSource(this.props); 35 } 36 37 onSend(message) { 38 const room = this.props.navigation.state.params.room; 39 this.setState((previousState) => ({ 40 messages: GiftedChat.append(previousState.messages, message), 41 })); 42 43 this.props.sendMessage({ 44 message, 45 room 46 }) 47 } 48 49 componentWillReceiveProps(nextProps) { 50 this.createDataSource(nextProps); 51 } 52 53 createDataSource({ messages }) { 54 const ds = new ListView.DataSource({ 55 rowHasChanged: (r1, r2) => r1 !== r2 56 }); 57 58 this.dataSource = ds.cloneWithRows(messages); 59 console.log('messages', messages); 60 61 // messagesを置く場所を間違えている? 62 this.setState({ messages }); 63 } 64 65 render() { 66 const { currentUser } = firebase.auth(); 67 return ( 68 <Screen> 69 <GiftedChat 70 messages={this.state.messages} 71 onSend={this.onSend.bind(this)} 72 user={{ 73 _id: currentUser.uid 74 }} 75 renderBubble={this.renderBubble} 76 renderSend={this.renderSend} 77 /> 78 </Screen> 79 ); 80 } 81}

上のコンソールログでは下記の結果が返ってきているのですが。。

コンソールログ結果

ListViewにするのが間違っているのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HayatoKamono

2018/04/21 02:20

そのエラーはどのタイミングで生じているのでしょうか?初期表示の段階で?`onSend`などもコードでみられますが、それが実行された後にエラーが出るとかでなければ、今回の質問に不要な部分は削ったミニマムなコードに修正することは可能ですか?逆に、reduxとの繋がりが今のコードで見えないので、その辺は省かずに入れた方がわかりやすいです。reducerやstoreのコードは不要です。
HayatoKamono

2018/04/21 02:28 編集

> ListViewにするのが間違っているのでしょうか? そもそも、render部分でListViewは使っていないですよね?datasource作っている割にそれをどこにも使っていなかったりしますし。 ListView周りのコードを削っても今と変わらないのでは?GiftedChatコンポーネントがうまいことリスト表示をしてくれるということなのではないですか?このライブラリを使ったことがないので詳細はわからないですが。
guest

回答1

0

ベストアンサー

「修正依頼欄」に記載したこととは別に、一旦、仮の回答を載せておきます。

1

{ _id: 1, text: 'My message', createdAt: new Date(Date.UTC(2016, 5, 11, 17, 20, 0)), user: { _id: 2, name: 'React Native', avatar: 'https://facebook.github.io/react/img/logo_og.png', }, image: 'https://facebook.github.io/react/img/logo_og.png', // Any additional custom parameters are passed through }

https://github.com/FaridSafi/react-native-gifted-chat#example

とりあえず、利用されているモジュールのドキュメントに書いてある例を参考に、_idキーを入れてみましょうか。

このモジュールのドキュメントは例こそ載っているものの、どういった形式のメッセージオブジェクトを渡さないといけないのかが明確に記載されていないので、ちょっとわかりづらいですね。

prepareMessages(messages) { return { keys: messages.map((m) => m._id), blob: messages.reduce((o, m, i) => { const previousMessage = messages[i + 1] || {}; const nextMessage = messages[i - 1] || {}; // add next and previous messages to hash to ensure updates const toHash = JSON.stringify(m) + previousMessage._id + nextMessage._id; o[m._id] = { ...m, previousMessage, nextMessage, hash: md5(toHash), }; return o; }, {}), }; }

https://github.com/FaridSafi/react-native-gifted-chat/blob/master/src/MessageContainer.js#L62

ということで、使用モジュールのソースコードをみてみると、やはり、_idキーがメッセージオブジェクト内に存在していることを前提にしているようなので、_idが必要になってくると思います。

2

// messagesを置く場所を間違えている? this.setState({ messages });

のところと、

messages={this.state.messages}

ですが、redux storeからmessagesを取ってきているのですよね?
であれば、this.props.messagesで直接参照できるはずなので、わざわざ、Messageコンポーネントのstateに入れて、this.state.messagesのように参照する必要がないと思います。

// messagesを置く場所を間違えている? this.setState({ messages });

なので、これは不要ですし、

// messages={this.state.messages} messages={this.props.messages}

で、良いと思います。

ただ、this.props.messagesundefinedだとエラーになるので、そこは、undefinedであれば、[]Messageコンポーネントに渡すようにしておくか、Messageコンポーネントのデフォルトのprops.messagesを[]のようにしておくかしておく必要はあるとおもいます。

3

ListViewにするのが間違っているのでしょうか?

「修正依頼欄」にも記載しましたが、ListViewは使わないでOKだと思います。

利用しているGiftedChatライブラリ自体が内部でListViewを使っています。

https://github.com/FaridSafi/react-native-gifted-chat/blob/master/src/MessageContainer.js#L152

createDataSource({ messages }) { const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); this.dataSource = ds.cloneWithRows(messages); console.log('messages', messages); // messagesを置く場所を間違えている? this.setState({ messages }); }

なので、この辺のdatasource周りのこともGiftedChatライブラリの内部で行われているので、この辺のコードも削除で問題ないと思います。

https://github.com/FaridSafi/react-native-gifted-chat/blob/master/src/MessageContainer.js#L30

投稿2018/04/21 03:01

編集2018/04/21 03:07
HayatoKamono

総合スコア2415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yamady

2018/04/21 04:00

Hayatoさま、いつも迅速なヘルプをくださりありがとうございます。 ここにきて、ようやく無事にチャットを作動するところまでできました。 ListViewは非推奨ですし、messagesのところをわざわざstateで入れ替えなくてもそのまま、this.props.messagesにすれば良いというのが、まさに答えでした。 自分で気づくべきでしたが、ドキュメントやそのほかのやり方を見て、少し引っ張られてしまったところがあったかと思います。。 苦労はしたものの、よくみるChat機能を動かせるのをみると感動がありますね・・!ありがとうございました!
HayatoKamono

2018/04/21 04:21

おー、良かったですね。おめでとうございます。
lulu

2018/07/12 14:20

同じ問題で困っています。idを指定しなかったのが原因です。 正しいコードを教えてください
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問