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

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

ただいまの
回答率

90.84%

  • React.js

    605questions

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

  • React Native

    123questions

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

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

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 171

yamady

score 130

なんども本当にすみません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に問題があるのでしょうか・・・

 ソースコード

class Message extends React.Component {
  static navigationOptions = ({ navigation }) => {
    return {
      headerTitle: `${navigation.state.params.room.user.name}`,
      headerLeft: (
        <TouchableOpacity
          onPress={()=> navigation.goBack()}
          style={styles.headerIcon}
        >
          <Icon name='chevron-left' size={28} style={{color: '#fff'}}/>
        </TouchableOpacity>
      ),
      headerStyle: {
        backgroundColor: Theme.PRIMARY,
      },
      headerTitleStyle: {
        color: '#fff',
        fontWeight: 'bold'
      }
    };
  };

  constructor(props) {
    super(props);
    this.state = {
      messages: [],
    };
  }

  componentWillMount() {
    const room = this.props.navigation.state.params.room;
    this.props.messagesFetch(room);

    this.createDataSource(this.props);
  }

  onSend(message) {
    const room = this.props.navigation.state.params.room;
    this.setState((previousState) => ({
      messages: GiftedChat.append(previousState.messages, message),
    }));

    this.props.sendMessage({
      message,
      room
    })
  }

  componentWillReceiveProps(nextProps) {
    this.createDataSource(nextProps);
  }

  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 });
  }

  render() {
    const { currentUser } = firebase.auth();
    return (
      <Screen>
        <GiftedChat
          messages={this.state.messages}
          onSend={this.onSend.bind(this)}
          user={{
            _id: currentUser.uid
          }}
          renderBubble={this.renderBubble}
          renderSend={this.renderSend}
        />
      </Screen>
    );
  }
}


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

コンソールログ結果

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • HayatoKamono

    2018/04/21 11:20

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

    キャンセル

  • HayatoKamono

    2018/04/21 11:28 編集

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

    キャンセル

  • HayatoKamono

    2018/04/21 11:23

    ちなみに、ListViewはdeprecatedです。https://facebook.github.io/react-native/docs/listview.html

    キャンセル

回答 1

checkベストアンサー

+1

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

 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 13:00

    Hayatoさま、いつも迅速なヘルプをくださりありがとうございます。
    ここにきて、ようやく無事にチャットを作動するところまでできました。

    ListViewは非推奨ですし、messagesのところをわざわざstateで入れ替えなくてもそのまま、this.props.messagesにすれば良いというのが、まさに答えでした。

    自分で気づくべきでしたが、ドキュメントやそのほかのやり方を見て、少し引っ張られてしまったところがあったかと思います。。
    苦労はしたものの、よくみるChat機能を動かせるのをみると感動がありますね・・!ありがとうございました!

    キャンセル

  • 2018/04/21 13:21

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

    キャンセル

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

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • React.js

    605questions

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

  • React Native

    123questions

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