🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Redux

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

Q&A

解決済

2回答

1857閲覧

mapStateToPropsが上手くいかない【TypeScript&connected-react-router&thunk】

southernX

総合スコア5

Redux

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

0グッド

0クリップ

投稿2019/10/10 16:05

編集2019/10/11 15:06

前提・実現したいこと

SignInコンポーネントにstateをpropsとして渡す。

該当のソースコード

SignInコンポーネント↓

SignIntsx

1import * as React from 'react'; 2import { connect } from 'react-redux' 3import { logInIfFetchUser } from '../modules/ActionCreater' 4import { AppState } from '../modules/Reducers' 5 6 7type SignInProps = { 8 logInIfFetchUser: any 9 user: any 10} 11class SignIn extends React.Component<SignInProps> { 12 render(){ 13 let email: any 14 let password: any 15 16 return( 17 <div> 18 <h1>サインイン</h1> 19 <p>{this.props.user}</p> 20 <form onSubmit={(e) => { 21 e.preventDefault() 22 console.log(`searching user with email: ${email.value}, password: ${password.value}`) 23 this.props.logInIfFetchUser(email.value, password.value) 24 }}> 25 <input type='text' ref={node => email = node}/> 26 <input type='password' ref={node => password = node}/> 27 <button type='submit'>ログイン</button> 28 </form> 29 </div> 30 ) 31 } 32} 33 34const mapStateToProps = (state: AppState) => { 35 user: state.userReducer 36} 37 38export default connect(mapStateToProps,{ logInIfFetchUser })(SignIn) 39

Reducer↓

import * as React from 'react'; import { connect } from 'react-redux' import { logInIfFetchUser } from '../modules/ActionCreater' import { AppState } from '../modules/Reducers' type SignInProps = { logInIfFetchUser: any user: any } class SignIn extends React.Component<SignInProps> { render(){ let email: any let password: any return( <div> <h1>サインイン</h1> <p>{this.props.user}</p> <form onSubmit={(e) => { e.preventDefault() console.log(`searching user with email: ${email.value}, password: ${password.value}`) this.props.logInIfFetchUser(email.value, password.value) }}> <input type='text' ref={node => email = node}/> <input type='password' ref={node => password = node}/> <button type='submit'>ログイン</button> </form> </div> ) } } const mapStateToProps = (state: AppState) => { user: state.userReducer } export default connect(mapStateToProps,{ logInIfFetchUser })(SignIn)

Action↓

import * as React from 'react'; import { connect } from 'react-redux' import { logInIfFetchUser } from '../modules/ActionCreater' import { AppState } from '../modules/Reducers' type SignInProps = { logInIfFetchUser: any user: any } class SignIn extends React.Component<SignInProps> { render(){ let email: any let password: any return( <div> <h1>サインイン</h1> <p>{this.props.user}</p> <form onSubmit={(e) => { e.preventDefault() console.log(`searching user with email: ${email.value}, password: ${password.value}`) this.props.logInIfFetchUser(email.value, password.value) }}> <input type='text' ref={node => email = node}/> <input type='password' ref={node => password = node}/> <button type='submit'>ログイン</button> </form> </div> ) } } const mapStateToProps = (state: AppState) => { user: state.userReducer } export default connect(mapStateToProps,{ logInIfFetchUser })(SignIn)

Store↓

Storejs

1import { createStore } from 'redux' 2import { applyMiddleware } from "redux"; 3import thunk from 'redux-thunk'; 4import { createBrowserHistory } from 'history' 5import { routerMiddleware } from 'connected-react-router' 6import { rootReducer } from "./Reducers"; 7 8export const history = createBrowserHistory() 9 10export const store = createStore( 11 rootReducer(history), 12 applyMiddleware( 13 routerMiddleware(history), 14 thunk 15 ) 16) 17

発生している問題・エラーメッセージ

mapStateToPropsの引数state(store)には確かにuserReducerが入っています。
エディターで確認できました。

イメージ説明

しかしuserReducerにカーソルを当ててみるとstateにはuserReducerが無いらしいのです
イメージ説明

こちらはコンソールの結果です。mapStateToPropsはundifinedになってしまいました。
イメージ説明

【追記】 Storeの構造、型を調べるためconsole.log(store.getState())をindex.jsで実行したところ、コンソールの結果は次のようになりました。
イメージ説明
確かにReducerは入っていて、それはmapStateToPropsでstate.userReducer.***として取り出せるはずと考えているのですが。

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんにちは

SignInコンポーネントをredux に connect させるときに渡している mapStateToProps

修正前:

javascript

1const mapStateToProps = (state: AppState) => { 2 user: state.userReducer 3}

となっていますが、以下のように { ・・・ } を丸カッコで囲んでみるといかがでしょうか?

修正後:

javascript

1const mapStateToProps = (state: AppState) => ({ 2 user: state.userReducer 3})

※参考: MDN アロー関数 - 構文 からの引用:

// object リテラル式を返す場合は、本体を丸括弧 () で囲みます:
params => ({foo: bar})

投稿2019/10/12 10:54

jun68ykt

総合スコア9058

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

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

southernX

2019/10/12 17:56

丸括弧をつける事で解決しました。回答ありがとうございます!奇遇にも、自分でも別作業をしている時に「あそこ丸括弧をつけたらどうかな」と考えていました笑。
jun68ykt

2019/10/12 18:01

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

0

キャプチャの1枚目で表示されている

TypeScript

1state: Reducer<{ 2 router: RouterState; 3 userReducer: userReducerState; 4}, AnyAction>

は型定義の情報なので、この時点ではオブジェクトが実際にあるかどうか確認できていません。(AppStateの情報も同様)
createStoreする時に渡しているreducerは、 combineReducers をしたものですか?
参考: combineReducersでハマったメモ

投稿2019/10/11 00:17

guissy-k

総合スコア245

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

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

southernX

2019/10/11 13:21

はい、rootReducerはconnectRouterとuserReducerをcombineReducers()したものです。stateの型ですがtype AppState = ReturnType<typeof rootReducer>として実際に返した値の型なのでAppState型の引数stateには確かにuserReducerがあるはずなのです。Storeのファイルも載せておきます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問