teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

コードの間違い

2018/10/04 00:47

投稿

sixth13
sixth13

スコア33

title CHANGED
File without changes
body CHANGED
@@ -54,45 +54,155 @@
54
54
 
55
55
  ```Pagination
56
56
  import React from 'react';
57
- import Pagination from './Pagination';
57
+ import PropTypes from 'prop-types';
58
+ import { BrowserRouter, Route, Link } from 'react-router-dom'
58
59
 
59
- class App extends React.Component {
60
- constructor() {
60
+ const propTypes = {
61
+ items: PropTypes.array.isRequired,
62
+ onChangePage: PropTypes.func.isRequired,
63
+ initialPage: PropTypes.number,
64
+ pageSize: PropTypes.number,
61
- super();
65
+ currentPage: PropTypes.number
66
+ }
62
67
 
63
- // an example array of items to be paged
68
+ const defaultProps = {
64
- var exampleItems = [...Array(150).keys()].map(i => ({ id: (i+1), name: 'Item ' + (i+1) }));
69
+ initialPage: 1,
70
+ pageSize: 10
71
+ }
65
72
 
73
+ class Pagination extends React.Component {
74
+ constructor(props) {
75
+ super(props);
66
- this.state = {
76
+ this.state = { pager: {} };
77
+ const reg = /\d+$/;
78
+ const url = String(location.href)
67
- exampleItems: exampleItems,
79
+ const notInitialPage = reg.test(url)
68
- pageOfItems: []
80
+ // currentPage = url.match(reg)[0]
81
+ // console.log(currentPage)
69
- };
82
+ }
70
83
 
84
+ componentWillMount() {
85
+ // set page if items array isn't empty
86
+ if (this.props.items && this.props.items.length) {
71
- this.onChangePage = this.onChangePage.bind(this);
87
+ this.setPage(this.props.initialPage);
88
+ }
72
89
  }
73
90
 
74
- onChangePage(pageOfItems) {
91
+ componentDidUpdate(prevProps, prevState) {
75
- // update state with new page of items
92
+ // reset page if items array has changed
93
+ if (this.props.items !== prevProps.items) {
76
- this.setState({ pageOfItems: pageOfItems });
94
+ this.setPage(this.props.initialPage);
95
+ }
77
96
  }
78
97
 
98
+ setPage(page) {
99
+ var { items, pageSize } = this.props;
100
+ var pager = this.state.pager;
101
+
102
+ if (page < 1 || page > pager.totalPages) {
103
+ return;
104
+ }
105
+
106
+ // get new pager object for specified page
107
+ pager = this.getPager(items.length, page, pageSize);
108
+
109
+ // get new page of items from items array
110
+ var pageOfItems = items.slice(pager.startIndex, pager.endIndex + 1);
111
+
112
+ // update state
113
+ this.setState({ pager: pager });
114
+
115
+ // call change page function in parent component
116
+ this.props.onChangePage(pageOfItems);
117
+ }
118
+
119
+ getPager(totalItems, currentPage, pageSize) {
120
+ // default to first page
121
+ currentPage = currentPage || 1;
122
+
123
+ // default page size is 10
124
+ pageSize = pageSize || 10;
125
+
126
+ // calculate total pages
127
+ var totalPages = Math.ceil(totalItems / pageSize);
128
+
129
+ var startPage, endPage;
130
+ if (totalPages <= 10) {
131
+ // less than 10 total pages so show all
132
+ startPage = 1;
133
+ endPage = totalPages;
134
+ } else {
135
+ // more than 10 total pages so calculate start and end pages
136
+ if (currentPage <= 6) {
137
+ startPage = 1;
138
+ endPage = 10;
139
+ } else if (currentPage + 4 >= totalPages) {
140
+ startPage = totalPages - 9;
141
+ endPage = totalPages;
142
+ } else {
143
+ startPage = currentPage - 5;
144
+ endPage = currentPage + 4;
145
+ }
146
+ }
147
+
148
+ // calculate start and end item indexes
149
+ var startIndex = (currentPage - 1) * pageSize;
150
+ var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);
151
+
152
+ // create an array of pages to ng-repeat in the pager control
153
+ var pages = [...Array((endPage + 1) - startPage).keys()].map(i => startPage + i);
154
+
155
+ // return object with all pager properties required by the view
156
+ return {
157
+ totalItems: totalItems,
158
+ currentPage: currentPage,
159
+ pageSize: pageSize,
160
+ totalPages: totalPages,
161
+ startPage: startPage,
162
+ endPage: endPage,
163
+ startIndex: startIndex,
164
+ endIndex: endIndex,
165
+ pages: pages
166
+ };
167
+ }
168
+
79
169
  render() {
170
+ var pager = this.state.pager;
171
+
172
+ if (!pager.pages || pager.pages.length <= 1) {
173
+ // don't display pager if there is only 1 page
174
+ return null;
175
+ }
176
+
80
177
  return (
81
- <div>
178
+ <BrowserRouter>
82
- <div className="container">
179
+ <ul className="pagination">
83
- <div className="text-center">
180
+ <li className={pager.currentPage === 1 ? 'disabled' : ''}>
84
- {this.state.pageOfItems.map(item =>
85
- <div key={item.id}>{item.name}</div>
181
+ <a onClick={() => this.setPage(1)}>First</a>
182
+ </li>
183
+ <li className={pager.currentPage === 1 ? 'disabled' : ''}>
184
+ <a onClick={() => this.setPage(pager.currentPage - 1)}>Previous</a>
185
+ </li>
186
+ {pager.pages.map((page, index) =>
187
+ <li key={index} className={pager.currentPage === page ? 'active' : ''}>
188
+ <Link to={page.toString()} onClick={() => this.setPage(page)}>{page}</Link>
189
+ </li>
86
- )}
190
+ )}
191
+ <li className={pager.currentPage === pager.totalPages ? 'disabled' : ''}>
87
- <Pagination items={this.state.exampleItems} onChangePage={this.onChangePage} />
192
+ <a onClick={() => this.setPage(pager.currentPage + 1)}>Next</a>
88
- </div>
193
+ </li>
194
+ <li className={pager.currentPage === pager.totalPages ? 'disabled' : ''}>
195
+ <a onClick={() => this.setPage(pager.totalPages)}>Last</a>
89
- </div>
196
+ </li>
90
- </div>
197
+ </ul>
198
+ </BrowserRouter>
91
199
  );
92
200
  }
93
201
  }
94
202
 
203
+ Pagination.propTypes = propTypes;
204
+ Pagination.defaultProps = defaultProps;
95
- export default App;
205
+ export default Pagination;
96
206
  ```
97
207
 
98
208
  ```index