7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

history.pushでurlは変わるのに画面遷移しないときの対処法

Last updated at Posted at 2021-01-31

はじめに

React(react-router-dom)で画面遷移をさせようと思った時にブラウザの表示しているURLは変わるのに画面が遷移しなかったので、その時の対処法を書き残します。

先に原因と対処法が見たい方はこちら

環境

  • Ubuntu 20.4
  • Node 12.18.3
  • npm 6.14.6
  • npx 6.14.6

画面遷移させるアプリケーションを作る(現象の再現)

Reactアプリのテンプレートから作成

まずはともかくcreate-react-app
今回はTypeScriptを使用。

npx create-react-app my-app --template typescript

react-router-domのインストール

cd my-app
npm i react-router-dom
npm i --save-dev @types/react-router-dom

画面遷移するアプリケーションへ変更

それぞれのページにボタンを配置し、ボタンをクリックした際にhistory.push()を実行し画面に遷移させる。

App.tsx
import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  useHistory
} from "react-router-dom";
import Home from './Home'
import Pages from './Pages'

const App: React.FC = () => {
  const history = useHistory()

  const goToHome = () => {
    history.push('/')
  }
  const goToPages = () => {
    history.push('/pages')
  }
  return (
    <Router>
      <Switch>
        <Route exact path='/'>
          <Home goToPages={goToPages}/>
        </Route>
        <Route exact path='/pages'>
          <Pages goToHome={goToHome}/>
        </Route>
      </Switch>
    </Router>
  );
}

export default App;

Home.tsx
import React from 'react'

interface Prop {
  goToPages: () => void,
}
const Home: React.FC<Prop> = (props) => {
  const { goToPages } = props
  return (
    <div>
      <h1>ホームだよ</h1>
      <button onClick={goToPages}>Pagesへ</button>
    </div>
  )
}

export default Home

Pages.tsx
import React from 'react'

interface Prop {
  goToHome: () => void,
}
const Pages: React.FC<Prop> = (props) => {
  const { goToHome } = props
  return (
    <div>
      <h1>ページだよ</h1>
      <button onClick={goToHome}>ホームへ</button>
    </div>
  )
}

export default Pages
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import {
  BrowserRouter as Router,
} from "react-router-dom";
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

  • index.tsx
    • App.tsxで使用しているuseHistoryがRouterコンポーネント内にないと動作しないため、とりあえずRouterで囲う
  • App.tsx
    • Switch,Routeによるページ遷移
  • Home.tsx Pages.tsx
    • ページ遷移ボタン設置

そしてnpm start

reactRouterNG.gif

・・・うーん??
ボタンをクリックした際にURLは変わっているが、画面が変わらない。
リロードをするときちんとそのページが表示される。

#原因と対処法
App.tsxindex.tsxにRouterが重複して存在している。
→Routerの子コンポーネントにRouterが存在している

App.tsx
import React from "react";
import {
  Switch,
  Route,
  useHistory
} from "react-router-dom";
import Home from './Home'
import Pages from './Pages'

function App() {
  const history = useHistory()

  const goToHome = () => {
    history.push('/')
  }
  const goToPages = () => {
    history.push('/pages')
  }
  return (
    <Switch>{/**ここ */}
      <Route exact path='/'>
        <Home goToPages={goToPages} />
      </Route>
      <Route exact path='/pages'>
        <Pages goToHome={goToHome} />
      </Route>
    </Switch>
  );
}

export default App;


変更して再度実行

reactRouterOK.gif

・・・いい感じ!!

まとめ

今回はApp.tsxにページ遷移の関数を作成し、Propsとして渡して実行するというパターンでした。
index.tsxではなくApp.tsx内にBrowserRouter(Router)を配置する際にはそれぞれのページコンポーネント(Home,Pages)にuseHistoryを記述するといいと思います。

アプリケーションにはBrowserRouter(Router)は一つと覚えておくといいと思います。

今後も精進していきます。

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?