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

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

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

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

Redux

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

React.js

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

Q&A

0回答

1533閲覧

React Routerで同じ階層の同じ構造の内容だとRedux Formの中身が更新されない

k10a

総合スコア35

Firebase

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

Redux

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

React.js

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

0グッド

0クリップ

投稿2020/01/20 12:06

React Routerと、Redux Formでアプリを作っています。

少し分かりづらい構造なのですが、コンテンツAの編集を/post/contents_aで、/post/contents_bではコンテンツBの内容を編集できるような仕組みを設けています。

問題は**Link_toを使って、/post/contents_aから、/post/contents_bに移動した時に、Redux Formで作成したテキストエリアのvalue部分が更新されない(テキストが表示されない)**ことです。fetch自体は毎回されているみたいなのですが、value部分に反映されてくれなくて困っています。

Routeのコンポネーントは無関係なところを省くと、下記になります。

JavaScript

1function App() { 2 return ( 3 <Provider store={store}> 4 <BrowserRouter> 5 <div> 6 <Switch> 7 <Route path="/post/contents_a" component={ContentsA} /> 8 <Route path="/post/contents_b" component={ContentsB} /> 9 </Switch> 10 </div> 11 </BrowserRouter> 12 </Provider> 13 ); 14}

ComponentsAは下記のようになっていて、ContentsBも、contentの部分がbになっているだけの違いです。

JavaScript

1import React, { Component } from "react"; 2import { connect } from "react-redux"; 3import { Field, reduxForm } from "redux-form"; 4import { fetchContent, updateContent } from "../../actions"; 5import { required } from "../../config/validate"; 6 7import ContentForm from "../common/form/content_form"; 8 9class ContentA extends Component { 10 constructor(props) { 11 super(props); 12 this.state = { 13 success: false 14 }; 15 } 16 17 componentDidMount() { 18 // bの場合はここがbになる 19 this.props.fetchContent('a'); 20 } 21 22 // componentDidUpdate(prevProps) { 23 // if (prevProps.location.pathname !== this.props.location.pathname) { 24 // this.props.fetchContent('b'); 25 // } 26 // } 27 28 onSubmit = values => { 29 const { content } = this.props; 30 this.props.updateContent(content, values); 31 this.setState({ success: true }); 32 }; 33 34 render() { 35 const { handleSubmit, content, history } = this.props; 36 return ( 37 <form className="formContent" onSubmit={handleSubmit(this.onSubmit)}> 38 <Field 39 label={"内容"} 40 name="content" 41 value={content.text} 42 component={ContentForm} 43 validate={required} 44 /> 45 <div className="formBtn"> 46 <button type="submit" className="btn btnPrimary"> 47 Save Changes 48 </button> 49 </div> 50 {this.state.success ? ( 51 <p className="formSuccess">Save Success!</p> 52 ) : ( 53 <div /> 54 )} 55 </form> 56 ); 57 } 58} 59 60const mapDispatchToProps = { fetchContent, updateContent }; 61 62function mapStateToProps({ contents, location }) { 63 return { 64 content: contents, 65 location: location, 66 initialValues: { 67 text: contents.text 68 } 69 }; 70} 71 72export default connect( 73 mapStateToProps, 74 mapDispatchToProps 75)( 76 reduxForm({ form: "contentsForm", enableReinitialize: true })(ContentA) 77);

ContentFormは下記のように設定しています。(/form/content_form)

JavaScript

1import React from "react"; 2 3const ContentForm = ({ 4 input, 5 label, 6 placeholder, 7 meta: { touched, error } 8}) => { 9 return ( 10 <div className="formItem"> 11 <p>{label}</p> 12 <textarea {...input} rows="6" /> 13 <p className="errorForm">{touched && error && <span>{error}</span>}</p> 14 </div> 15 ); 16}; 17 18export default ContentForm;

Redux部分はこちらのようになっています。

JavaScript

1// Fetch content 2export function fetchContent(category) { 3 return dispatch => { 4 firebase.auth().onAuthStateChanged(user => { 5 contentsRef 6 .where("uid", "==", user.uid) 7 .where("category", "==", category) 8 .get() 9 .then(function(querySnapshot) { 10 querySnapshot.forEach(function(doc) { 11 dispatch({ type: FETCH_CONTENT, payload: doc.data() }); 12 }); 13 }); 14 }); 15 }; 16} 17 18// Update content 19export function updateContent(content, values) { 20 return dispatch => { 21 contentsRef 22 .where("uid", "==", content.uid) 23 .where("category", "==", content.category) 24 .get() 25 .then(function(querySnapshot) { 26 querySnapshot.forEach(function(doc) { 27 doc.ref.update({ 28 text: values.text 29 }); 30 dispatch({ type: UPDATE_CONTENT }); 31 }); 32 }); 33 }; 34}

JavaScript

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

JavaScript

1import { createStore, applyMiddleware, combineReducers } from "redux"; 2import ContentsReducer from "./reducer_contents.js"; 3import reduxThunk from "redux-thunk"; 4import { reducer as formReducer } from "redux-form"; 5 6const rootReducer = combineReducers({ 7 contents: ContentsfReducer, 8 form: formReducer 9}); 10 11const store = createStore(rootReducer, applyMiddleware(reduxThunk)); 12export default store;

コメントアウトしてますが、componentsDidUpdate()で再描画試みたりしてみたのですが、どうしてもできませんでした。どなたかお知恵を拝借させていただけますと幸いです。

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

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

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

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

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

og24715

2020/01/22 08:14

わがままで申し訳ないですが、これだけ複雑になってくると回答の負担が大きいです。最小コードに落とし込むか stackblitz で実際に動くコードを提示されたほうが回答しやすくなるかと思います。力になりたいところですが私はコードを読むのを諦めました。
k10a

2020/01/22 08:53

コメントいただきまして本当にありがとうございます。そうですよね、かなりコードが複雑ですよね。 今一度自分の中で整理してまいりたいと思います。
og24715

2020/01/22 09:02

質問の趣旨とは異なりますが、特に理由がなければ redux-form の代わりに formik の採用をおすすめします。過去にどちらも使いましたが、formik はコンポーネント自体でフォームの入力状態の管理を完結できるので簡潔です。redux-form の readme にも同様の理由で formik を使用するように勧めています。
k10a

2020/01/22 09:34

ありがとうございます。こちらに移行してみることも検討してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問