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

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

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

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

React.js

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

Q&A

0回答

767閲覧

reactでページネーションを実装し、そこにURLでも制御できるようreact-routerを実装したい

sixth13

総合スコア33

Router

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

React.js

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

0グッド

0クリップ

投稿2018/10/03 06:10

編集2022/01/12 10:55

reactでページネーションを実装し、そこにURLでも制御できるようreact-routerを実装したいです。
ページネーションは実装例がよくあるのでそれを参考にしました。

react-routerはV4を採用しました

そこにブラウザの[戻る]ボタンやURLに直に打っても動作できるようにするにはどのようにすればよろしいでしょうか。
ご教示頂ければ幸いです。

今はページネーションを押したらURLが変わる、ブラウザの[戻る]でURLが変わる以外の動作のみです。
ページネーションのみは完動です。

App

1import React from 'react'; 2import Pagination from './Pagination'; 3 4class App extends React.Component { 5 constructor() { 6 super(); 7 8 // an example array of items to be paged 9 var exampleItems = [...Array(150).keys()].map(i => ({ id: (i+1), name: 'Item ' + (i+1) })); 10 11 this.state = { 12 exampleItems: exampleItems, 13 pageOfItems: [] 14 }; 15 16 this.onChangePage = this.onChangePage.bind(this); 17 } 18 19 onChangePage(pageOfItems) { 20 // update state with new page of items 21 this.setState({ pageOfItems: pageOfItems }); 22 } 23 24 render() { 25 return ( 26 <div> 27 <div className="container"> 28 <div className="text-center"> 29 {this.state.pageOfItems.map(item => 30 <div key={item.id}>{item.name}</div> 31 )} 32 <Pagination items={this.state.exampleItems} onChangePage={this.onChangePage} /> 33 </div> 34 </div> 35 </div> 36 ); 37 } 38} 39 40export default App;

Pagination

1import React from 'react'; 2import PropTypes from 'prop-types'; 3import { BrowserRouter, Route, Link } from 'react-router-dom' 4 5const propTypes = { 6 items: PropTypes.array.isRequired, 7 onChangePage: PropTypes.func.isRequired, 8 initialPage: PropTypes.number, 9 pageSize: PropTypes.number, 10 currentPage: PropTypes.number 11} 12 13const defaultProps = { 14 initialPage: 1, 15 pageSize: 10 16} 17 18class Pagination extends React.Component { 19 constructor(props) { 20 super(props); 21 this.state = { pager: {} }; 22 const reg = /\d+$/; 23 const url = String(location.href) 24 const notInitialPage = reg.test(url) 25 // currentPage = url.match(reg)[0] 26 // console.log(currentPage) 27 } 28 29 componentWillMount() { 30 // set page if items array isn't empty 31 if (this.props.items && this.props.items.length) { 32 this.setPage(this.props.initialPage); 33 } 34 } 35 36 componentDidUpdate(prevProps, prevState) { 37 // reset page if items array has changed 38 if (this.props.items !== prevProps.items) { 39 this.setPage(this.props.initialPage); 40 } 41 } 42 43 setPage(page) { 44 var { items, pageSize } = this.props; 45 var pager = this.state.pager; 46 47 if (page < 1 || page > pager.totalPages) { 48 return; 49 } 50 51 // get new pager object for specified page 52 pager = this.getPager(items.length, page, pageSize); 53 54 // get new page of items from items array 55 var pageOfItems = items.slice(pager.startIndex, pager.endIndex + 1); 56 57 // update state 58 this.setState({ pager: pager }); 59 60 // call change page function in parent component 61 this.props.onChangePage(pageOfItems); 62 } 63 64 getPager(totalItems, currentPage, pageSize) { 65 // default to first page 66 currentPage = currentPage || 1; 67 68 // default page size is 10 69 pageSize = pageSize || 10; 70 71 // calculate total pages 72 var totalPages = Math.ceil(totalItems / pageSize); 73 74 var startPage, endPage; 75 if (totalPages <= 10) { 76 // less than 10 total pages so show all 77 startPage = 1; 78 endPage = totalPages; 79 } else { 80 // more than 10 total pages so calculate start and end pages 81 if (currentPage <= 6) { 82 startPage = 1; 83 endPage = 10; 84 } else if (currentPage + 4 >= totalPages) { 85 startPage = totalPages - 9; 86 endPage = totalPages; 87 } else { 88 startPage = currentPage - 5; 89 endPage = currentPage + 4; 90 } 91 } 92 93 // calculate start and end item indexes 94 var startIndex = (currentPage - 1) * pageSize; 95 var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1); 96 97 // create an array of pages to ng-repeat in the pager control 98 var pages = [...Array((endPage + 1) - startPage).keys()].map(i => startPage + i); 99 100 // return object with all pager properties required by the view 101 return { 102 totalItems: totalItems, 103 currentPage: currentPage, 104 pageSize: pageSize, 105 totalPages: totalPages, 106 startPage: startPage, 107 endPage: endPage, 108 startIndex: startIndex, 109 endIndex: endIndex, 110 pages: pages 111 }; 112 } 113 114 render() { 115 var pager = this.state.pager; 116 117 if (!pager.pages || pager.pages.length <= 1) { 118 // don't display pager if there is only 1 page 119 return null; 120 } 121 122 return ( 123 <BrowserRouter> 124 <ul className="pagination"> 125 <li className={pager.currentPage === 1 ? 'disabled' : ''}> 126 <a onClick={() => this.setPage(1)}>First</a> 127 </li> 128 <li className={pager.currentPage === 1 ? 'disabled' : ''}> 129 <a onClick={() => this.setPage(pager.currentPage - 1)}>Previous</a> 130 </li> 131 {pager.pages.map((page, index) => 132 <li key={index} className={pager.currentPage === page ? 'active' : ''}> 133 <Link to={page.toString()} onClick={() => this.setPage(page)}>{page}</Link> 134 </li> 135 )} 136 <li className={pager.currentPage === pager.totalPages ? 'disabled' : ''}> 137 <a onClick={() => this.setPage(pager.currentPage + 1)}>Next</a> 138 </li> 139 <li className={pager.currentPage === pager.totalPages ? 'disabled' : ''}> 140 <a onClick={() => this.setPage(pager.totalPages)}>Last</a> 141 </li> 142 </ul> 143 </BrowserRouter> 144 ); 145 } 146} 147 148Pagination.propTypes = propTypes; 149Pagination.defaultProps = defaultProps; 150export default Pagination;

index

1import React from 'react'; 2import ReactDOM from 'react-dom'; 3import App from './components/App'; 4 5ReactDOM.render(<App />, document.getElementById('app'));

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問