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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

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

Q&A

解決済

2回答

1598閲覧

react-reduxでstateを更新した時に再レンダリングする方法

dds

総合スコア11

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

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

1グッド

0クリップ

投稿2019/06/15 16:16

編集2019/06/15 23:23

前提・実現したいこと

react-reduxでstateを更新した時に再レンダリングして画面に描画したいです。

該当のソースコード

index.js

javascript

1import React, { Component } from "react"; 2import { connect } from "react-redux"; 3import * as actions from "../actions"; 4 5class App extends Component { 6 renderResult() { 7 console.log(this.props.result); 8 if (!this.props.result) { 9 return <div>No Result!!!</div>; 10 } else { 11 return <div>{this.props.result}</div>; 12 } 13 } 14 15 render() { 16 return ( 17 <div> 18 <button onClick={this.props.getGenders}>get genders</button> 19 {this.renderResult()} 20 </div> 21 ); 22 } 23} 24 25const mapStateToProps = state => { 26 return { result: state.result }; 27}; 28 29export default connect( 30 mapStateToProps, 31 actions 32)(App); 33

action

Javascript

1import axios from "axios"; 2import { GET_GENDERS } from "./types"; 3 4export const getGenders = () => async dispatch => { 5 try { 6 const response = await axios.get("http://localhost:3090/gender"); 7 dispatch({ type: GET_GENDERS, payload: response.data }); 8 } catch (e) { 9 console.log("error"); 10 } 11};

reducer

javascript

1import { GET_GENDERS } from "../actions/types"; 2 3const INITIAL_STATE = { 4 result: "" 5}; 6 7export default function(state = INITIAL_STATE, action) { 8 switch (action.type) { 9 case GET_GENDERS: 10 return { ...state, result: action.payload }; 11 default: 12 return state; 13 } 14}

試したこと

button(getGenders)をクリックした時にAction内でaxiosのリクエストが発行され、reducers側で正しくstateが更新されることは確認できています。(Reduxのstate上はgenders > resultにxmlの結果が格納されています)
上記JavaScriptのthis.renderResult()の箇所でうまく再レンダリングさせて画面上に表示させたいのですが、どのように実装すれば良いでしょうか。
アドバイスいただけると幸いです。

jun68ykt👍を押しています

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

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

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

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

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

jun68ykt

2019/06/15 18:35

アクションクリエータとリデューサーのソースコードも質問に追記頂けると、より多くの回答が得られるかもしれません。
dds

2019/06/15 23:24

追記致しました。ありがとうございます!
jun68ykt

2019/06/16 05:40

追記ありがとうございます。どこがおかしいのか見始めていますが、あともう2点だけ確認させてください。(1) たぶん合ってると思いますが念のための確認です。Redux と非同期処理の連携のために、 redux-thunk をお使いでしょうか? (2) ご質問の中に、「 resultにxmlの結果が格納されています」とあったので、 http://localhost:3090/gender によってXMLが返され、やりたいことは、このレスポンスのXML全体を文字列として redux state の genders.result に入れ、これを画面に <div>で囲って表示したい、ということでよいでしょうか?
dds

2019/06/16 09:07 編集

(1) redux-thunkを利用しています! ```index.js import React from "react"; import ReactDOM from "react-dom"; import { Provider } from "react-redux"; import { createStore, applyMiddleware, compose } from "redux"; import reduxThunk from "redux-thunk"; import reducers from "./reducers"; import App from "./components/App"; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore( reducers, composeEnhancers(applyMiddleware(reduxThunk)) ); ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.querySelector("#root") ); ``` (2) はい、そうです!正確にはそのxmlの中身を加工して画面に出力、、ということを後ほど実施したいのですが、直近の目標として全て出力することをしたいです!
jun68ykt

2019/06/16 16:46

ご返信ありがとうございます。回答しました。
guest

回答2

0

ベストアンサー

こんにちは

ここが怪しいのでは?と思うところを回答します。ご質問の中に

(Reduxのstate上はgenders > resultにxmlの結果が格納されています)

とあったので、App をreduxに connect するときの mapStateToProps を以下のように修正してみるといかがでしょうか?

修正前:

javascript

1const mapStateToProps = state => { 2 return { result: state.result }; 3};

修正後:

javascript

1const mapStateToProps = state => { 2 return { result: state.genders.result }; // state と result の間に genders 追加 3};

参考になれば幸いです。

備考

ご質問にあるコードを集めて、Reactアプリを作り、以下に上げておきましたので、参考にしてみてください。

足りない部分はこちらで適宜補いました。またaxios のリクエスト先は mockable.io に適当に作成しました。また、redux-logger を追加して、アクション前後のstateの内容をコンソールで確認できるようにしています。

上記の回答に書いた修正に相当するコミットは、以下です。

この修正によって、ボタンをクリックすると、レスポンスに入っているXMLが以下のように表示されました。

イメージ説明

投稿2019/06/16 15:35

編集2019/06/16 15:49
jun68ykt

総合スコア9058

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

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

dds

2019/06/16 22:09

こちら、ご指摘の内容を修正し、解決いたしました。 jun68yktさん詳しいご解説ありがとうございました。mm
jun68ykt

2019/06/16 23:22

どういたしまして。解決されたようでよかったです ????
guest

0

Reactでは基本的にComponentに渡ってくるpropsが更新されると再レンダリングされますが、
今回は変更したい部分が単純なJSの関数呼び出しになっているので、最初の1回目にrender関数が実行された際にrenderResultを実行すると、それ以降はpropsが変更されても再レンダリングされない状態になっているようです。

下記のようにすると意図通りに動くかと思います。

javascript

1class App extends Component { 2 render() { 3 return ( 4 <div> 5 <button onClick={this.props.getGenders}>get genders</button> 6 {this.props.result ? <div>{this.props.result}</div> : <div>No Result!!!</div> } 7 </div> 8 ); 9 } 10} 11

投稿2019/06/15 16:36

編集2019/06/15 16:38
gyarasu

総合スコア148

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

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

dds

2019/06/15 23:28

ご回答ありがとうございます! 変更してみましたが、変化は得られませんでした。stateの変更を常にみてくれるわけではないんですね。 (情報が不足しているとのご指摘もありましたので、actionとreducerの情報も追記致しました)
gyarasu

2019/06/16 03:05

`componentDidUpdate()`を追加して中で適当にconsole.logして、ボタン押したときにコンソールに出力されるか見ていただけますか? もしかしたらcomponentとredux storeがうまく接続できてないのかもしれません
dds

2019/06/16 09:05

`componentDidUpdate()` を追加してみました!確かに何も出力されないです。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問