前提・実現したいこと
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
回答1件
あなたの回答
tips
プレビュー