#reactjs #pagination #html-select
#reactjs #разбивка на страницы #html-выберите
Вопрос:
Я очень новичок в react и столкнулся с проблемой разбивки на страницы / выпадающего списка select. У меня есть компонент разбивки на страницы, который я создал из примера 1 и примера 2. Я извлек выпадающий список в его собственный компонент.
Я могу выбирать страницы разбивки на страницы, я также могу выбрать выпадающий список, чтобы изменить страницу разбивки на страницы.
Проблема: если я нахожусь на последней странице выпадающего списка и меняю выпадающий список на другой вариант, дополнительная страница «-1» добавляется в начало страницы разбивки на страницы…
Например: Начальное количество страниц выбрано равным 2, в пейджере отображаются страницы с 1 по 14. Выберите количество страниц до 10, перейдите на последнюю страницу. Выберите количество страниц равным 2, в пейджере отображаются страницы -1, 1 — 14. Я не уверен, откуда берется значение -1, но при повторении варианта использования появляется больше -1.
Я думал, что проблема заключалась в этом разделе в компоненте разбивки на страницы, но не повезло…
// pager pages
for (let i = startPage; i < groupCount startPage; i ) {
// console.log(startPage);
if (i <= totalPages - 1) {
pages.push(<li onClick={e => getPage(i)} className={currentPage === i ? styles.active : ""} key={i} id={i}>{i}</li>);
}
}
Я включил приведенный ниже код и GIF-изображение ошибки. Я был бы признателен за любую помощь в изучении кода или направлении меня в правильном направлении. Заранее спасибо!
Компонент разбивки на страницы
function Pagination(props) {
// get items from object
const items = props.items;
// get items count from items.total_count
const itemsLength = items.length;
// const [dataLength, setDataLength] = useState(props.itemsLength);
const [pageCount, setPageCount] = useState(props.pageCount);
// get total # of pages for pager
const totalPages = Math.ceil(itemsLength/pageCount);
const [currentPage, setCurrentPage] = useState(props.currentPage);
const [groupCount, setGroupCount] = useState(props.groupCount);
const [startPage, setStartPage] = useState(props.startPage);
const [paging, setPaging] = useState({
currentPage: '',
pageCount: ''
});
const displayCountOptions = props.displayCountOptions ? (
<DropDownSelect
legend={props.viewOptionHelpText}
options={props.viewOptions}
defaultSelectedOption={0}
selectionID={props.viewOptionID}
changeFunc={e => confirmPageCount(e.target.value)}
size={props.viewOptionSize}
layout={props.viewOptionLayout}
/>
) : ('');
function createPager(totalPages) {
let pages = [];
if (totalPages <= 10) {
// previous
pages.push(<li onClick={e => getPrev(currentPage)} className={currentPage === 1 ? styles.nomore : ""} key={0}>Prev</li>);
// pager pages
for (let i = 1; i <= totalPages; i ) {
pages.push(<li onClick={e => getPage(i)} className={currentPage === i ? styles.active : ""} key={i}>{i}</li>);
}
// next
pages.push(<li onClick={e => getNext(currentPage, totalPages)} className={currentPage === totalPages ? styles.nomore : ""} key={totalPages 1}>Next</li>);
} else {
// previous
pages.push(<li onClick={e => getPrev(currentPage)} className={currentPage === 1 ? styles.nomore : ""} key={0}>Prev</li>);
// if startPage is greater than groupCount
if (startPage > groupCount) {
// set first page as 1
pages.push(<li onClick={e => getPage(1)} className={currentPage === 1 ? styles.active : ""} key={1}>1</li>);
// ellipsis ...
pages.push(<li onClick={e => getPage(startPage - groupCount)} className={styles.ellipsis} key={-2}>···</li>);
}
// pager pages
for (let i = startPage; i < groupCount startPage; i ) {
// console.log(startPage);
if (i <= totalPages - 1) {
pages.push(<li onClick={e => getPage(i)} className={currentPage === i ? styles.active : ""} key={i} id={i}>{i}</li>);
}
}
// ellipsis ...
if (totalPages - startPage > groupCount) {
pages.push(<li onClick={e => getPage(startPage groupCount)} className={styles.ellipsis} key={-1}>···</li>);
}
// last page
pages.push(<li className={currentPage === totalPages ? styles.active : ""} key={totalPages} onClick={e => getPage(totalPages)}>{totalPages}</li>);
// next
pages.push(<li onClick={e => getNext(currentPage, totalPages)} className={currentPage === totalPages ? styles.nomore : ""} key={totalPages 1}>Next</li>);
}
return pages;
}
function getPage(currentPage, reset = false) {
setCurrentPage(currentPage);
// console.log(currentPage);
// handles getPage for prev page
if (currentPage % groupCount === 1) {
setStartPage(currentPage);
}
// handles getPage for next page
if (currentPage % groupCount === 0) {
setStartPage(currentPage - groupCount 1);
}
// last page
if (totalPages - currentPage < 1) {
setStartPage(totalPages - groupCount);
}
if (reset === true) {
setCurrentPage(1);
setStartPage(1);
}
setTimeout(()=>{
setPaging({
currentPage: currentPage,
pageCount: pageCount
});
});
// console.log(paging);
}
function getPrev(currentPage) {
if (--currentPage === 0) {
return;
}
getPage(currentPage);
}
function getNext(currentPage) {
if ( currentPage > totalPages) {
return;
}
getPage(currentPage);
}
function confirmPageCount(pageCount){
setPageCount(pageCount);
console.log(pageCount);
console.log(totalPages);
setTimeout(()=>{
getPage(currentPage, true);
}, 0);
}
const [upperLimit, setUpperLimit] = useState(undefined);
const [paginatedData, setPaginatedData] = useState([]);
function createPaginatedData(pageCount) {
setUpperLimit(currentPage * pageCount);
const itemsSlice = items.slice((upperLimit - pageCount), upperLimit);
setPaginatedData(itemsSlice);
}
useEffect(() => {
createPaginatedData(pageCount);
}), [pageCount];
const pages = createPager(totalPages);
return(
<React.Fragment>
<div className={styles.main}>
{displayCountOptions}
<ul className={styles.page}>
{pages}
</ul>
</div>
<div className='pagination-results'>
{React.cloneElement(props.children, {items: paginatedData})}
</div>
</React.Fragment>
);
}
Компонент DropDownSelect
function DropDownSelect(props) {
// const { themeContext } = useContext(ThemeContext);
const dropDownSelectGroup = cx({
dropDownSelectGroup: true,
[`${props.layout}`]: true,
// [`${themeContext.theme}Theme`]: true
});
const dropDownSelections = cx({
dropDownSelections: true
});
const selectionsUl = cx({
[`${props.size}`]: true,
hide: true
});
const [defaultOption, setDefaultOption] = useState(props.defaultSelectedOption);
const [selected, setSelected] = useState(defaultOption);
const [pageCountEle, setPageCountEle] = useState(undefined);
function createLabel(item) {
var splitItem = item.split(/[ ,] /).filter(Boolean);
var finalItem = splitItem.join('');
return 'select' finalItem;
}
const selectID = props.selectionID ? props.selectionID : '';
useEffect(() => {
setPageCountEle(document.querySelector(`#${selectID}`));
});
const legend = props.legend ? (
<label htmlFor={createLabel(props.legend)} className={styles.helpText}>{props.legend}</label>
) : (
''
);
// props changefunc takes in a function and attach it to when drop down select value is changed
function handleChange(e) {
//if prevent default is false, use html submit, not this function
if (!props.preventDefault) {
return;
}
//stop html submit
e.preventDefault();
//execute the changeFunc function passed in via props
props.changeFunc(e);
}
function changeOption(e) {
// console.log(e.target);
pageCountEle.innerHTML = e.target.innerHTML;
pageCountEle.parentNode.className = selectionsUl;
pageCountEle.parentNode.className = " " styles.hide;
}
function chooseOption(e){
// console.log(e);
const parentUI = e.parentNode;
// console.log(pageCountEle.parentNode);
if (parentUI.classList.contains(styles.hide)) {
parentUI.classList.remove(styles.hide);
} else {
parentUI.className = " " styles.hide;
}
}
const selections = props.options ? (
<div className={dropDownSelections}>
<ul
className={selectionsUl}
value={defaultOption}
>
<li
id={selectID}
onClick={e => chooseOption(e.target)}
>{props.options[defaultOption].label}</li>
{props.options.map((option, index) => {
return <li id={option.value} key={index} value={option.value}
onClick={e => {changeOption(e); handleChange(e);}}
>{option.label}</li>
})}
</ul>
</div>
) : (
''
);
return (
<div className={dropDownSelectGroup}>
{legend}
{selections}
</div>
);
}