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

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

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

Routerは、異なるネットワーク同士を相互に接続するための通信機器。インターネットでのデータを自動的に振り分け、一つのインターネット回線を複数のコンピュータで使用することが可能です。DHCPによりIPアドレスを自動的に割振りすることもできます。

SPA(Single-page Application)

SPA(Single-page Application)は、単一のWebページのみでコンテンツの切り替えができるWebアプリケーションもしくはWebサイトです。ブラウザでのページ遷移がないため、デスクトップアプリケーションのようなUXを提供します。

JavaScript

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

React.js

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

Q&A

解決済

1回答

4773閲覧

React Routerでクエリストリングが付与された際に再描画(レンダリング)したい

toshiki_

総合スコア11

Router

Routerは、異なるネットワーク同士を相互に接続するための通信機器。インターネットでのデータを自動的に振り分け、一つのインターネット回線を複数のコンピュータで使用することが可能です。DHCPによりIPアドレスを自動的に割振りすることもできます。

SPA(Single-page Application)

SPA(Single-page Application)は、単一のWebページのみでコンテンツの切り替えができるWebアプリケーションもしくはWebサイトです。ブラウザでのページ遷移がないため、デスクトップアプリケーションのようなUXを提供します。

JavaScript

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

React.js

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

0グッド

0クリップ

投稿2021/01/03 04:26

編集2021/01/03 05:43

前提・実現したいこと

React Routerを利用したルーティング。
クエリストリングが追加されたURLにアクセスした際に再描画したい。

開発環境

※package.jsonのdependenciesを記載します。
こちらで不足ありましたらお手数ですが何を載せたら良いかご教示いただけますと幸いです。

json

1 ... 2 "dependencies": { 3 "@testing-library/jest-dom": "^5.11.4", 4 "@testing-library/react": "^11.1.0", 5 "@testing-library/user-event": "^12.1.10", 6 "react": "^17.0.1", 7 "react-dom": "^17.0.1", 8 "react-scripts": "4.0.1", 9 "web-vitals": "^0.2.4" 10 } 11 ...

ソース

App.js

javascript

1import Dog from './Dog'; 2 3import { 4 BrowserRouter as Router, 5 Switch, 6 Route, 7 Link 8} from "react-router-dom"; 9 10const App = () => { 11 12 return ( 13 <Router> 14 <Switch> 15 16 <Route path="/"> 17 <Dog /> 18 </Route> 19 20 </Switch> 21 </Router> 22 ); 23} 24 25export default App;

Dog.js

javascript

1import { useEffect, useState } from 'react' 2import { Link, useHistory } from "react-router-dom"; 3 4import axios from 'axios' 5 6const Dog = () => { 7 8 const [ imageUrl, setImageUrl ] = useState('') 9 10 useEffect(() => { 11 axios({ 12 method: 'get', 13 url: 'https://dog.ceo/api/breeds/image/random' 14 }).then(response => { 15 setImageUrl(response['data']['message']) 16 }) 17 }, []) 18 19 return ( 20 <> 21 <h1>Dog image</h1> 22 <img src={ imageUrl } alt='dog'/> 23 <p>{ imageUrl }</p> 24 <ul> 25 <li><Link to='/'>Top</Link></li> 26 <li><Link to='/?page=2'>Next</Link></li> 27 <NextPageButton /> 28 </ul> 29 </> 30 ) 31 32} 33 34export default Dog 35 36const NextPageButton = ()=> { 37 const history = useHistory(); 38 return <button onClick={()=> { 39 history.push('/?page=3'); 40 }}>click me!</button>; 41}

試したこと

aタグやLinkの他にもソース内にあるhistory.pushを使用してURLの変更なども試してみましたがだめでした。。
かなりggったのですがなかなかこれだ、というものが見当たらず。

補足情報

React Hooks勉強中です。
まずは色々な機能を持つSPAを試しに作っているところなのですがルーティングでハマりました…。

現在React Routerを使用してルーティングを実装しています。
https://reactrouter.com/web/guides/quick-start

以下のようにクエリストリングにパラメータを渡した際にレンダリングしてほしいのですが、URLが変わるだけでレンダリングしてくれません。

http://localhost:3000/
http://localhost:3000/?page=2
http://localhost:3000/?page=3

正確にはuseEffectが実行されずに困っています。

Reactは画面に表示している内容に差分がないと再描画しない、というところは理解しています。
しかし、今回のようにクエリストリングがあってURLが変更された場合にAPIをコールしてくれないため、困っています。

解決方法のアドバイスを教えていただけますと幸いです。

参考URL

調査している際に目を通して関係がありそうだと思ったURLです。

公式
react-routerで現在のlocationを取得する2種類の方法の使い分け方
React入門 ~React Router編~
React RouterがHooks対応したので使い方を整理する
Reactがrenderの内容を更新してくれなくてハマった
react-router 同ページ内で再描画されない解決メモ

(修正)パスパラメータを利用した形に修正

App.js

javascript

1import Dog from './Dog'; 2 3import { 4 BrowserRouter as Router, 5 Switch, 6 Route, 7 Link 8} from "react-router-dom"; 9 10const App = () => { 11 12 return ( 13 <Router> 14 <Switch> 15 16 <Route exact path="/"> 17 <Dog /> 18 </Route> 19 20 <Route path="/page:pageNum"> 21 <Dog /> 22 </Route> 23 24 </Switch> 25 </Router> 26 ); 27} 28 29export default App;

Dog.js

javascript

1import { useEffect, useState } from 'react' 2import { Link, useHistory, useParams } from 'react-router-dom'; 3 4import axios from 'axios' 5 6const Dog = () => { 7 8 const [ imageUrl, setImageUrl ] = useState('') 9 10 useEffect(() => { 11 axios({ 12 method: 'get', 13 url: 'https://dog.ceo/api/breeds/image/random' 14 }).then(response => { 15 setImageUrl(response['data']['message']) 16 }) 17 }, []) 18 19 let { pageNum } = useParams(); 20 if (typeof pageNum === 'undefined') { 21 pageNum = 1 22 } 23 24 return ( 25 <> 26 <h1>Dog image</h1> 27 <h2>{ pageNum }ページ目</h2> 28 <img src={ imageUrl } alt='dog'/> 29 <p>{ imageUrl }</p> 30 <ul> 31 <li><Link to='/'>Top</Link></li> 32 <li><Link to='/page2'>Next</Link></li> 33 </ul> 34 </> 35 ) 36} 37 38export default Dog

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

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

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

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

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

toshiki_

2021/01/03 05:42

回答ありがとうございます! すみません、公式にあったのですね。。 確かにおっしゃるとおりパスパラメータを使用したほうがスムーズに実装できそうですのでそちらをまず試してみました。 ※概要欄にソースを載せています。 ですが、こちらでもやはりuseEffectが実行されずapiがコールされないまま「nページ目」の部分だけが更新されてしまう状態です。 こちら解決方法に心当たりがありましたらご教示いただければと思います…。
guest

回答1

0

自己解決

確かにおっしゃるとおりパスパラメータを使用したほうがスムーズに実装できそうですのでそちらをまず試してみました。
※概要欄にソースを載せています。

ですが、こちらでもやはりuseEffectが実行されずapiがコールされないまま「nページ目」の部分だけが更新されてしまう状態です。

上記ですが、hooksの公式ドキュメントを読み直し、追加したpageNumをuseEffectの第2引数に入れることで実現できました。

javascript

1 useEffect(() => { 2 axios({ 3 method: 'get', 4 url: 'https://dog.ceo/api/breeds/image/random' 5 }).then(response => { 6 setImageUrl(response['data']['message']) 7 }) 8 }, [pageNum])

ありがとうございました。

投稿2021/01/03 05:54

toshiki_

総合スコア11

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問