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

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

ただいまの
回答率

90.34%

  • React.js

    911questions

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

  • Firebase

    670questions

    Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

  • React Native

    196questions

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

firebaseで配列の単体をfetchできない(react native)

解決済

回答 1

投稿 編集

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

yamady

score 151

毎度失礼いたしますmm

react nativeでチャット投稿を実現したいと思っています。
(これで3回目の質問になります。)

Firebaseでチャット機能を実現したい(react native)
gifted chatでmessageをDBからFetchしたい(react native)

 実現したいこと&困っていること

ReferenceError: message is not defined


Message.jsのmessages: GiftedChat.append(previousState.messages, message),でつっかえています。ここには、既にFirebaseに保存されているデータベースが取ってこれるはずなのですが、このmessageを取ってくることができなくて困っています。

こちらのソースコードをRedux仕様にして、チャット機能を実装したいのですが、保存は成功しているのですが

Firebase保存画面

message2は下記のコンソール情報が取ってこれています。

イメージ説明

ここのvalueを一つずつmessageの中にsetStateしてあげたいのですが><

 ソースコード

Message.js

class Message extends React.Component {
  state = {
    messages: [],
  }

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

    console.log('message3, message);
    this.setState((previousState) => {
      return {
        messages: GiftedChat.append(previousState.messages, message),
      };
    });
  }

  onSend = (message) => {
    const room = this.props.navigation.state.params.room;
    this.props.sendMessage({
      message,
      room
    });
  }

  renderBubble(props) {
    return (
      <Bubble
        {...props}
        wrapperStyle={{
          right: {
            backgroundColor: Theme.SECONDARY
          }
        }}
      />
    )
  }

  renderSend(props) {
    return (
      <Send
      {...props}
      textStyle={{
        color: Theme.SECONDARY
      }}
      />
    );
  }

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

const mapStateToProps = (state) => {
  const { text, user, createdAt, _id } = state.messageForm;
  return { text, user, createdAt, _id };
};

export default connect(mapStateToProps, {
  sendMessage,
  messagesFetch
})(Message);

redux/messageActions.js

/**
* Builds an action to request
*/
export const sendMessage = ({ message, room }) => {
  const { currentUser } = firebase.auth();
  return (dispatch) => {
    firebase.database().ref(`/rooms/${room.roomId}/messages/`)
    .push({
      text: message[0].text,
      user: message[0].user,
      createdAt: firebase.database.ServerValue.TIMESTAMP,
    })
    .then(() => {
      dispatch({ type: 'message_create' });
    });
  }
}

/**
* Builds an action to notification fetch action
*/
export const messagesFetch = (room) => {
  return (dispatch) => {
    firebase.database().ref(`/rooms/${room.roomId}/messages/`)
    .once('value', snapshot => {
      const message = snapshot.val();
      return message;
    })
    .then(message => {
      dispatch({ type: 'messages_fetch_success', payload: message });
      console.log('message2', message);
    });
  };
};

messageReducer.js

 type uiActions = {
   type: 'messages_fetch_success',
 }

 const initialState = {};

 export default (state = initialState, action) => {
   switch (action.type) {
     case 'messages_fetch_success':
       return action.payload;
     default:
       return state;
   }
 };

messageFormReducer.js

/**
 * @flow
 *
 * Manages the state of all Message Form components which rely on Redux
 */

 type uiActions = {
   type: 'message_update',
   type: 'message_create,'
 }

 const initialState = {
   text: '',
   user: '',
   createdAt: '',
   _id: '',
   roomId: ''
 };

 export default (state = initialState, action) => {
   switch(action.type) {
     case 'message_update':
       return { ...state, [action.payload.prop]: action.payload.value };
     case 'message_create':
       return initialState;
     default:
       return state;
   }
 };

store.js

const rootReducer = combineReducers({
  messages: messageReducer,
  messageForm: messageFormReducer
});

const store = createStore(
  rootReducer,
  applyMiddleware(reduxThunk)
);
export default store;
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

ComoponentDidMountが効いていないように思います

というのは、具体的にどういった状況を表しているのですか?

meesage1, message2は取れて来ていますが、message3はエラーすら出ません(無視されている?)

このコードで本当にmessage1message2ってログで取れてますか?

  componentDidMount() {
    this.props.messagesFetch((message) => {
      console.log('message3', message);
      this.setState((previousState) => {
        return {
          messages: GiftedChat.append(previousState.messages, message),
        };
      });
    });
  };

というのも、redux/messageActions.jsを見る限り、messagesFetch関数が取る引数はroomオブジェクトのようですが、componentDidMount内でのmessagesFetch関数の呼び出しでは関数オブジェクトを引数に渡していますよね?

それと、これは単なる確認ですが、redux/messageActions.jsを見る限り、利用しているmiddlewareはredux-thunkっぽいですが、それで合っていますか?

 追記1

return message;
      console.log('message1', message);

いや、console.logの前にreturnしているので、message1は間違いなくログで取れないですよね?
今一度、状況を整理して質問内容を見直した方が良さそうですよ。

 追記2

追記の内容を確認いたしました。

message3はエラーすら出ませんと当初ありましたが、編集後のコードのどこでmessageを参照したいのですか?

質問内容をわかりやすくするために、引き続き、console.log(message3)をコード内に入れてください。

.then(message => {
      dispatch({ type: 'messages_fetch_success', payload: message });
      console.log('message2', message);
    });


messageFetch()関数の中でdispatchしていますが、ここでstoreに入れたものはMessage.jsのどこで取得していますか?

const mapStateToProps = (state) => {
  const { text, user, createdAt, _id } = state.messageForm;
  return { text, user, createdAt, _id };
};


ここで先ほどのところでdispatchしたmessage、またはmessagesを既に取っているのでしょうか?
取っていないのであれば、Messageコンポーネントの中でmessageを参照出来ないですよね。

必要であれば、{ type: 'messages_fetch_success', payload: message }に対応しているreducerのコードも追記してください。不要そうであれば、そちらのコードの追記も不要です。

 追記3

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

    console.log('message3, message);
    this.setState((previousState) => {
      return {
        messages: GiftedChat.append(previousState.messages, message),
      };
    });
  }

とりあえず、componentWillMount内でthis.props.messagesFetch(room)している訳ですから、このライフサイクルメソッド内でconsole.log('message3, message)のようにmessageを参照しようとしても、まだ、reduxのstoreにmessage入っていないので参照出来ません。このコンポーネント内で参照できるようになるのは、componentWillReceiveProps以降のライフサイクルメソッドです。

次に、そもそものところで、追記2にも書きましたが、mapStateToProps内でmessageを取ってないですよね。

const mapStateToProps = (state) => {
  const { text, user, createdAt, _id } = state.messageForm;
  return { text, user, createdAt, _id };
};


というか話は少し本題からずれますが、ここで参照しているtextやら userやらは、Messageコンポーネント内で一切使っていなくないですか?

前提として、reduxをどれくらい理解されてますでしょうか?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/20 03:43

    ご丁寧な回答本当にありがとうございます。
    いただいた指摘の箇所を今一度、確認して質問内容を修正してまいりますm(_ _)m

    キャンセル

  • 2018/04/20 06:11

    > それと、これは単なる確認ですが、redux/messageActions.jsを見る限り、利用しているmiddlewareはredux-thunkっぽいですが、それで合っていますか?

    こちらその通りです!

    キャンセル

  • 2018/04/20 16:58

    > Hayatoさま
    回答を編集して、ご指南いただきありがとうございます。質問内容にご指摘いただいた内容などを追記させていただきました。

    キャンセル

  • 2018/04/20 16:58

    分かりづらくてすみません。。

    キャンセル

  • 2018/04/21 09:02

    ご指摘をいただきまして、ありがとうございます。
    一旦、前には進めたようなので、また論点が変わってしまうと思うので
    別で質問させていただきます。

    いつも非常に助かります。

    キャンセル

  • 2018/04/21 09:03

    OKです!一つずつ問題点疑問点を潰しながら前に進めていけると良いですね!

    キャンセル

  • 2018/04/21 09:11

    reduxなど、ご指摘の通り、曖昧なまま進んでしまってきた感が否めません・・・。精進します!ありがとうございます(_ _)

    キャンセル

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

  • React.js

    911questions

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

  • Firebase

    670questions

    Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

  • React Native

    196questions

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