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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

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

Q&A

解決済

1回答

6526閲覧

react-redux-router,ConnectedRouterでエラー、"TypeError: Cannot read property 'dispatch' of undefined"

increment-P

総合スコア16

Redux

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

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

2グッド

1クリップ

投稿2019/01/21 01:53

編集2019/01/21 01:55

長文すみません。
react-redux-routerを勉強しているのですが、どのサンプルを入力しても同様のエラーが出て何か基本的な所で躓いているようなのですが解決できずに困っています。
ご指導いただけないでしょうか?

  • WSL ubuntu 18.04
  • yarn 1.13.0
  • npm 6.4.1

yarn add redux react-redux redux-thunk redux-logger react-router-dom react-router-redux@next history --dev
↓ インストール直後のpackage.jsonです

JavaScript

1{ 2 "name": "my-project", 3 "version": "0.1.0", 4 "private": true, 5 "dependencies": { 6 "react": "^16.7.0", 7 "react-dom": "^16.7.0", 8 "react-scripts": "2.1.3" 9 }, 10 "scripts": { 11 "start": "react-scripts start", 12 "build": "react-scripts build", 13 "test": "react-scripts test", 14 "eject": "react-scripts eject" 15 }, 16 "eslintConfig": { 17 "extends": "react-app" 18 }, 19 "browserslist": [ 20 ">0.2%", 21 "not dead", 22 "not ie <= 11", 23 "not op_mini all" 24 ], 25 "devDependencies": { 26 "history": "^4.7.2", 27 "react-redux": "^6.0.0", 28 "react-router-dom": "^4.3.1", 29 "react-router-redux": "^5.0.0-alpha.9", 30 "redux": "^4.0.1", 31 "redux-logger": "^3.0.6", 32 "redux-thunk": "^2.3.0" 33 } 34}

この後、fetch-jsonpとqsをインストールしています。

翔泳社のReact入門のサンプルを入力するとエラーとなって実行できません。

以下import等端折ったソースです。

__↓ src/index.js __

JavaScript

1const history = createBrowserHistory(); 2const store = createStore(history); 3 4ReactDOM.render( 5 <Provider store={store}> 6 <ConnectedRouter history={history}> 7 <App /> 8 </ConnectedRouter> 9 </Provider>, 10 document.getElementById('root') 11); 12

__↓ src/components/Nav.js 及び src/components/Ranking.js __

JavaScript

1//Nav.js 2export default function Nav({ categories }) { 3 const to = category => ( 4 category.id === '1' ? '/all' : `/category/${category.id}` 5 ); 6 7 return ( 8 <ul> 9 {categories.map(category => ( 10 <li key={`nav-item-${category.id}`}> 11 <Link to={to(category)}> 12 {category.name} 13 </Link> 14 </li> 15 ))} 16 </ul> 17 ); 18} 19Nav.propTypes = { 20 categories: PropTypes.arrayOf( 21 PropTypes.shape({ 22 id: PropTypes.string.isRequired, 23 name: PropTypes.string.isRequired 24 }) 25 ).isRequired 26}; 27 28 29//Ranking.js 30export default class Ranking extends React.Component { 31 componentWillMount() { 32 this.props.onMount(this.props.categoryId); 33 } 34 componentWillReceiveProps(nextProps) { 35 if (this.props.categoryId !== nextProps.categoryId) { 36 this.props.onUpdate(nextProps.categoryId); 37 } 38 } 39 40 render() { 41 const { category, ranking, error } = this.props; 42 43 return ( 44 <div> 45 <h2>{ 46 typeof category !== 'undefined' ? `${category.name}のランキング` : '' 47 }</h2> 48 49 {(() => { 50 if (error) { 51 return <p>エラーが発生しました。リロードしてください。</p>; 52 } else if (typeof ranking === 'undefined') { 53 return <p>読み込み中...</p>; 54 } else { 55 return ( 56 <ol> 57 {ranking.map(item => ( 58 <li key={`ranking-item-${item.code}`}> 59 <img alt={item.name} src={item.imageUrl} /> 60 <a href={item.url} target="_blank">{item.name}</a> 61 </li> 62 ))} 63 </ol> 64 ); 65 } 66 })()} 67 </div> 68 ); 69 } 70} 71Ranking.propTypes = { 72 categoryId: PropTypes.string.isRequired, 73 onMount: PropTypes.func.isRequired, 74 onUpdate: PropTypes.func.isRequired, 75 76 category: PropTypes.shape({ 77 id: PropTypes.string.isRequired, 78 name: PropTypes.string.isRequired, 79 }), 80 ranking: PropTypes.arrayOf( 81 PropTypes.shape({ 82 code: PropTypes.string.isRequired, 83 name: PropTypes.string.isRequired, 84 url: PropTypes.string.isRequired, 85 imageUrl: PropTypes.string.isRequired, 86 }) 87 ), 88 error: PropTypes.bool.isRequired 89}; 90Ranking.defaultProps = { 91 categoryId: '1' 92}; 93

__↓ src/containers/Nav.js 及び src/containers/Ranking.js __

JavaScript

1//Nav.js 2const mapStateToProps = state => ({ 3 categories: state.shopping.categories 4}); 5export default connect(mapStateToProps)(Nav); 6 7 8//Ranking.js 9const mapStateToProps = (state, ownProps) => ({ 10 categoryId: ownProps.categoryId, 11 12 category: state.Ranking.category, 13 ranking: state.Ranking.ranking, 14 error: state.Ranking.error 15}); 16 17const mapDispatchToProps = dispatch => ({ 18 onMount (categoryId) { 19 dispatch(actions.fetchRanking(categoryId)); 20 }, 21 onUpdate (categoryId) { 22 dispatch(actions.fetchRanking(categoryId)); 23 } 24}); 25export default connect(mapStateToProps, mapDispatchToProps)(Ranking);

__↓ src/reducers/index.js、src/reducers/Ranking.js 及び src/reducers/shopping.js __

JavaScript

1//index.js 2export { default as shopping } from './shopping'; 3export { default as Ranking } from './Ranking'; 4 5//Ranking.js 6const getRanking = response => { 7 const ranking = []; 8 const itemLength = response.ResultSet.totalResultsReturned 9 for (let index = 0; index < itemLength; index++) { 10 const item = response.ResultSet['0'].Result[index + '']; 11 ranking.push({ 12 code: item.Code, 13 name: item.Name, 14 url: item.Url, 15 imageUrl: item.Image.Medium 16 }) 17 } 18 return ranking; 19}; 20 21const initialState = { 22 category: undefined, 23 ranking: undefined, 24 error: false 25}; 26 27export default (state = initialState, action) => { 28 switch (action.type) { 29 case 'START_REQUEST': 30 return { 31 category: action.payload.category, 32 ranking: undefined, 33 error: false 34 }; 35 36 case 'RECEIVE_DATA': 37 return action.payload.error 38 ? { ...state, error: true } 39 : { ...state, ranking: getRanking(action.payload.response) }; 40 41 default: 42 return state; 43 } 44} 45 46//shopping.js 47const initialState = { 48 categories: [ 49 { id: '1', name: 'すべてのカテゴリ' }, 50 { id: '2502', name: 'パソコン、周辺機器' }, 51 { id: '10002', name: '本、雑誌、コミック' } 52 ] 53}; 54export default () => initialState;

__↓ src/actions/Ranking.js __

JavaScript

1const API_URL = 'yahooのAPIリクエストURL'; 2const APP_ID = '自分がyahooで取得したID'; 3 4const startRequest = category => ({ 5 type: 'START_REQUEST', 6 payload: { category }, 7}); 8const receiveData = (category, error, response) => ({ 9 type: 'RECEIVE_DATA', 10 payload: { category, error, response }, 11}); 12const finishRequest = category => ({ 13 type: 'FINISH_REQUEST', 14 payload: { category }, 15}); 16 17// ランキングを取得する 18export const fetchRanking = categoryId => { 19 return async (dispatch, getState) => { 20 const categories = getState().shopping.categories; 21 const category = categories.find(category => (category.id === categoryId)); 22 if (typeof category === 'undefined') { 23 dispatch(replace('/')); 24 return; 25 } 26 dispatch(startRequest(category)); 27 28 const queryString = qs.stringify({ 29 appid: APP_ID, 30 category_id: categoryId, 31 }); 32 try { 33 const responce = await fetchJsonp(`${API_URL}?${queryString}`); 34 const data = await responce.json(); 35 dispatch(receiveData(category, null, data)); 36 } catch (err) { 37 dispatch(receiveData(category, err)); 38 } 39 dispatch(finishRequest(category)); 40 }; 41}; 42

__ ↓ src/createStore.js __

JavaScript

1export default function createStore(history) { 2 return reduxCreateStore( 3 combineReducers({ 4 ...reducers, 5 router: routerReducer, 6 }), 7 applyMiddleware( 8 logger, 9 thunk, 10 routerMiddleware(history) 11 ) 12 ); 13}

__ ↓ src/fetchRanking.js __

JavaScript

1const API_URL = 'yahooのAPIリクエストURL'; 2const APP_ID = '自分がyahooで取得したID'; 3 4export default function fetchRanking(categoryId) { 5 const queryString = qs({ 6 appid: APP_ID, 7 category_id: categoryId 8 }); 9 return fetchJsonp(`${API_URL}?${qs}`); 10}

__ ↓ src/App.js __

JavaScript

1class App extends Component { 2 render() { 3 return ( 4 <div className="App"> 5 <Nav /> 6 <Switch> 7 <Route path="/all" component={Ranking} /> 8 <Route 9 path="/category/1" 10 render={() => <Redirect to="/all" />} 11 /> 12 <Route 13 path="/category/:id" 14 render={ 15 ({ match }) => <Ranking categoryId={match.params.id} /> 16 } 17 /> 18 </Switch> 19 </div> 20 ); 21 } 22} 23export default App;

__ ↓ src/index.js[エントリーポイント] __

JavaScript

1import React from 'react'; 2import ReactDOM from 'react-dom'; 3import { Provider } from 'react-redux'; 4import { ConnectedRouter } from 'react-router-redux'; 5import createBrowserHistory from 'history/createBrowserHistory'; 6import App from './App'; 7import createStore from './createStore'; 8 9const history = createBrowserHistory(); 10const store = createStore(history); 11 12ReactDOM.render( 13 <Provider store={store}> 14 <ConnectedRouter history={history}> 15 <App /> 16 </ConnectedRouter> 17 </Provider>, 18 document.getElementById('root') 19);

実行結果は
** TypeError: Cannot read property 'dispatch' of undefined **
となります。

プラウザコンソールのデバッガで追いかけたりしたのですが自己解決できそうにありません。
よろしくお願いします・

このサイトのサンプルでも同様のエラーが出ます。

hood, jun68ykt👍を押しています

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

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

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

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

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

jun68ykt

2019/01/25 02:38

こちらのご質問、解決されたようでしたら解決済みにして頂けますと幸いです。さらなる疑問があれば、コメント頂ければと思います。
guest

回答1

0

ベストアンサー

こんにちは

ご質問にある、 yarn add コマンド

yarn add redux react-redux redux-thunk redux-logger react-router-dom react-router-redux@next history --dev

が間違っているようです。具体的には最後の --dev が不要なので、いったん

yarn remove redux react-redux redux-thunk redux-logger react-router-dom react-router-redux@next history

でremoveしてから、あらためて --dev なしの

yarn add redux react-redux redux-thunk redux-logger react-router-dom react-router-redux@next history

yarn addしてから動作確認してみるとよいと思います。

ちなみにご質問に挙げているソースコードは、同書籍サンプルコードの以下のフォルダ

Ch10_sample/Ch10_sample/5-reducer

にあるものと思います (間違っていたらご指摘ください) が、ダウンロードしたサンプルコードに含まれる

  • Ch10_sample/Ch10_sample/5-reducer/package.json

は以下のようになっています。

json

1{ 2 "name": "1-add-redux", 3 "version": "0.1.0", 4 "private": true, 5 "dependencies": { 6 "fetch-jsonp": "^1.1.3", 7 "history": "^4.7.2", 8 "prop-types": "^15.6.0", 9 "qs": "^6.5.1", 10 "react": "^16.2.0", 11 "react-dom": "^16.2.0", 12 "react-redux": "^5.0.6", 13 "react-router-dom": "^4.2.2", 14 "react-router-redux": "^5.0.0-alpha.9", 15 "react-scripts": "1.1.0", 16 "redux": "^3.7.2", 17 "redux-logger": "^3.0.6", 18 "redux-thunk": "^2.2.0" 19 }, 20 "scripts": { 21 "start": "react-scripts start", 22 "build": "react-scripts build", 23 "test": "react-scripts test --env=jsdom", 24 "eject": "react-scripts eject" 25 } 26}

したがって、書籍の説明に沿うならば、ご質問にある package.json の "devDependencies" に追加されている以下のモジュール

json

1 "devDependencies": { 2 "history": "^4.7.2", 3 "react-redux": "^6.0.0", 4 "react-router-dom": "^4.3.1", 5 "react-router-redux": "^5.0.0-alpha.9", 6 "redux": "^4.0.1", 7 "redux-logger": "^3.0.6", 8 "redux-thunk": "^2.3.0" 9 }

は、 "dependencies" のほうに追加されるべきものです。ですので、 yarn add時に --dev が不要と思われました。

参考になれば幸いです。

追記

react router が 4.2 から 4.3 になった際に、react-router-redux のコミッタである @timdorrさんが以下のようにアナウンスしています。

https://twitter.com/timdorr/status/1004390317179785216

React Router 4.3.0 is out!

And I'm finally officially deprecating react-router-redux.

ですので、問題の原因は react router 4.3 と react-router-reduxを組み合わせて使おうとしたことによるものと思われます。ご自身で yarn add で各モジュールをインストールせずに、 書籍のサンプルにある package.json をそのまま使って、以下のように yarn install コマンドで各モジュールをインストールするほうがよいです。

[5-reducer]$ pwd /Users/jun68ykt/WebstormProjects/react-book/Ch10_sample/Ch10_sample/5-reducer [5-reducer]$ cat package.json { "name": "1-add-redux", "version": "0.1.0", "private": true, "dependencies": { "fetch-jsonp": "^1.1.3", "history": "^4.7.2", "prop-types": "^15.6.0", "qs": "^6.5.1", "react": "^16.2.0", "react-dom": "^16.2.0", "react-redux": "^5.0.6", "react-router-dom": "^4.2.2", "react-router-redux": "^5.0.0-alpha.9", "react-scripts": "1.1.0", "redux": "^3.7.2", "redux-logger": "^3.0.6", "redux-thunk": "^2.2.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" } } [5-reducer]$ yarn install yarn install v1.12.3 [1/4] ???? Resolving packages... (・・・中略) success Saved lockfile. ✨ Done in 22.35s. [5-reducer]$ yarn start

上記の手順で、意図通りの画面がブラウザに表示されると思います。

投稿2019/01/21 14:32

編集2019/01/24 08:47
jun68ykt

総合スコア9058

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

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

increment-P

2019/01/24 01:07

回答ありがとうございます。 dependenciesとdevDependenciesの違いが理解できていませんでした。 https://qiita.com/chihiro/items/ca1529f9b3d016af53ec ご指摘の通りyarnにてモジュールをインストールする際に "--dev"オプションを外してインストールしました。 "yarn add redux react-redux redux-thunk redux-logger react-router-dom react-router-redux@next history fetch-jsonp qs" 結果package.jsonは以下のようになりました。 { "name": "my-project2", "version": "0.1.0", "private": true, "dependencies": { "fetch-jsonp": "^1.1.3", "history": "^4.7.2", "qs": "^6.6.0", "react": "^16.7.0", "react-dom": "^16.7.0", "react-redux": "^6.0.0", "react-router-dom": "^4.3.1", "react-router-redux": "^5.0.0-alpha.9", "react-scripts": "2.1.3", "redux": "^4.0.1", "redux-logger": "^3.0.6", "redux-thunk": "^2.3.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": [ ">0.2%", "not dead", "not ie <= 11", "not op_mini all" ] } ですが、エラー内容は変わらず・・・。 "TypeError: Cannot read property 'dispatch' of undefined" ConnectedRouter._this.handleLocationChange node_modules/react-router-redux/es/ConnectedRouter.js:49 return _ret = (_temp = (_this = _possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.handleLocationChange = function (location) { _this.store.dispatch({ //←ここですと、、、 type: LOCATION_CHANGE, payload: location }); 試しにyarn add の"--exact"オプションを使ってサンプル側のモジュールのバージョンを指定してインストールしてみました。 "yarn add react@16.2.0 react-dom@16.2.0 react-redux@5.0.6 react-scripts@1.1.0 --exact prop-types@15.6.0 redux@3.7.2 react-redux@5.0.6 redux-logger@3.0.6 redux-thunk@2.2.0 react-router-dom@4.2.2 react-router-redux@5.0.0-alpha.9 history@4.7.2 fetch-jsonp@1.1.3 qs@6.5.1 --exact" こちらではきちんと動く事を確認しました。 試しに、 "yarn add redux react-redux redux-thunk redux-logger react-router-dom@next react-router-redux@next history fetch-jsonp qs" "react-router-dom"をnextでインストールしてみると、、、 同じエラーで変わらず。 とっかかりすら掴めず途方にくれています・・・。
jun68ykt

2019/01/24 08:13

@increment-Pさん 回答に追記しましたので、試してみてください。
increment-P

2019/01/24 13:12

理解できました。ありがとうございました。
jun68ykt

2019/01/25 02:35

解決されたようですね、よかったです????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問