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

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

ただいまの
回答率

88.63%

connected-react-routerを使ってurlを変えたのに表示されるコンポーネントが変わらない

受付中

回答 2

投稿 編集

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

aiai8976

score 81

前提・実現したいこと

以下のサイトと全く同じ状況が起きているのですが、自分の場合はもともとswitchを使っていました。
https://teratail.com/questions/216393
他の原因はどこにあるでしょうか。
わかる方がいましたら回答お願いします。

コンソール出力

action @@router/CALL_HISTORY_METHOD @ 23:59:06.455
redux-logger.js:388  prev state {noop: {…}, shopping: {…}, Ranking: {…}, router: {…}}Ranking: {category: undefined, ranking: undefined, error: false}noop: {}router: {location: {…}, action: "POP"}shopping: {categories: Array(3)}__proto__: Object
redux-logger.js:392  action     {type: "@@router/CALL_HISTORY_METHOD", payload: {…}}payload: {method: "push", args: Array(1)}args: ["/category/2502"]method: "push"__proto__: Objecttype: "@@router/CALL_HISTORY_METHOD"__proto__: Object
redux-logger.js:401  next state {noop: {…}, shopping: {…}, Ranking: {…}, router: {…}}Ranking: {category: undefined, ranking: undefined, error: false}noop: {}router: {location: {…}, action: "POP"}shopping: {categories: Array(3)}__proto__: Object
redux-logger.js:377  action @@router/LOCATION_CHANGE @ 23:59:06.457
redux-logger.js:388  prev state {noop: {…}, shopping: {…}, Ranking: {…}, router: {…}}
redux-logger.js:392  action     {type: "@@router/LOCATION_CHANGE", payload: {…}}payload: {location: {…}, action: "PUSH", isFirstRendering: false}type: "@@router/LOCATION_CHANGE"__proto__: Object
redux-logger.js:401  next state {noop: {…}, shopping: {…}, Ranking: {…}, router: {…}}

該当のソースコード

createStore.js

import {
  createStore as reduxCreateStore,
  combineReducers,
  applyMiddleware
} from 'redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
import { connectRouter, routerMiddleware } from 'connected-react-router';

import * as reducers from './reducers';

export default function createStore(history) {
  return reduxCreateStore(
    combineReducers({
      ...reducers,
      router: connectRouter(history), //ルーター状態を管理するルーターreducer
    }),
    applyMiddleware(
      logger,
      thunk,
      routerMiddleware(history)
    )
  );
}

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router';
import createBrowserHistory from 'history/createBrowserHistory';
import App from './App';
import createStore from './createStore';

const history = createBrowserHistory();

//Storeの生成
const store = createStore(history);

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App />
    </ConnectedRouter>
  </Provider>,
  document.getElementById('root')
);


App.js

import React, { Component } from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import Ranking from './containers/Ranking';
import Nav from './containers/Nav';
import Reboot from 'material-ui/Reboot';
import AppBar from 'material-ui/AppBar';
import Toolbar from 'material-ui/Toolbar';
import Typography from 'material-ui/Typography';

class App extends Component {
  render() {
    return (
      <div className="App" style={{ paddingLeft: 240 }}>
        <Reboot />

        <AppBar style={{ left: 240 }}>
          <Toolbar>
            <Typography type="title" color="inherit">
              Yahoo!ショッピングランキング
            </Typography>
          </Toolbar>
        </AppBar>

        <Nav />

        <div style={{ marginTop: 64, padding: 32 }}>
          <Switch>
            <Route path="/all" component={Ranking} />
            <Route
              path="/category/1"
              render={() => <Redirect to="/all" />}
            />
            <Route
              path="/category/:id"
              render={
                ({ match }) => <Ranking categoryId={match.params.id} />
              }
            />
          </Switch>
        </div>
      </div>
    );
  }
}

export default App;


components/Nav.js

import Drawer from 'material-ui/Drawer';
import List, { ListItem, ListItemText } from 'material-ui/List';
import PropTypes from 'prop-types';
import React from 'react';

export default function Nav({ categories, onClick }) {
  const to = category => (
    category.id === '1'
      ? `/all`
      : `/category/${category.id}`
  );

  return (
    <Drawer type="permanent">
      <List style={{ width: 240 }}>
        {categories.map(category => (
          <ListItem
            button
            key={`menu-item-${category.id}`}
            onClick={() => onClick(to(category))}
          >
            <ListItemText primary={category.name} />
          </ListItem>
        ))}
      </List>
    </Drawer>
  );
}

Nav.propTypes = {
  categories: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.string.isRequired,
      name: PropTypes.string.isRequired
    })
  ).isRequired,
  onClick: PropTypes.func.isRequired
};

containers/Nav.js

import { connect } from 'react-redux';
import { push } from 'connected-react-router';
import Nav from '../components/Nav';

const mapStateToProps = state => ({
  categories: state.shopping.categories
});

const mapDispatchToProps = dispatch => ({
  onClick(path) {
    dispatch(push(path)); 
  }
})

export default connect(mapStateToProps, mapDispatchToProps)(Nav);

reducers/Ranking.js

const getRanking = response => {
  const ranking = [];
  const itemLength = response.ResultSet.totalResultsReturned
  for (let index = 0; index < itemLength; index++) {
    const item = response.ResultSet['0'].Result[index + ''];
    ranking.push({
      code: item.Code,
      name: item.Name,
      url: item.Url,
      imageUrl: item.Image.Medium
    })
  }
  return ranking;
}

const initialState = {
  category: undefined,
  ranking: undefined,
  error: false
};

export default (state = initialState, action) => {
  switch (action.type) {
    case 'START_REQUEST':
      return {
        category: action.payload.category,
        ranking: undefined,
        error: false
      };

    case 'RECEIVE_DATA':
      return action.payload.error
        ? { ...state, error: true }
        : {
          ...state,
          ranking: getRanking(action.payload.response)
        };
    default:
      return state;
  }
}

試したこと

https://github.com/supasate/connected-react-router/issues/260
上記のサイトにバージョンを6.0.0にダウングレードさせるように記述されていましたが、試してみても変わりませんでした。
react-router-domとconnected-react-routerが依存関係があるようで、上の記事に書かれている場合すべての通りを試してみましたが、変化なしです。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

0

Nav.jsの

onClick={() => onClick(to(category))}


を、

onClick={() => to(category)}


に変えて見てください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

上記の回答は無視してください。
2点ほど確認していただきたいです。
storeの設定は、

// configureStore.js
...
import { createBrowserHistory } from 'history'
import { applyMiddleware, compose, createStore } from 'redux'
import { routerMiddleware } from 'connected-react-router'
import createRootReducer from './reducers'
...
export const history = createBrowserHistory()

export default function configureStore(preloadedState) {
  const store = createStore(
    createRootReducer(history), // root reducer with router state
    preloadedState,
    compose(
      applyMiddleware(
        routerMiddleware(history), // for dispatching history actions
        // ... other middlewares ...
      ),
    ),
  )

  return store
}


のようになっていますでしょうか?
また、App.jsでconsole.log(this.props)をしていただきたいです。
ReactはClassのpropsまたはstateが変わった時に再レンダリングします。なので、リンクが変わった際にpropsが変わっているのか確認していただきたいです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/11/05 00:03

    コメントありがとうございます。
    それぞれの対応は上に加えました。
    確認お願いします。

    キャンセル

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

  • ただいまの回答率 88.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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