#javascript #reactjs #rest
Вопрос:
Я получаю данные из API Django Rest и реагирую на интерфейс, и мне нужно создать разбиение на страницы с сообщениями. Я сделал все это в компоненте разбиения на страницы. Я создал состояние с текущей страницей и изменяю его, нажав на кнопку страница в компоненте, как это:
const Paginator = () => {
const [count, setCount] = useState(null);
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(null);
const [nextPage, setNextPage] = useState(null);
const [previousPage, setPreviousPage] = useState(null);
const [valid, setValid] = useState(false);
useEffect(() => {
fetch(`http://127.0.0.1:8000/api/software/?p=${currentPage}`)
.then(response => response.json())
.then(data => {
setCount(data.count);
setTotalPages(data.total_pages)
setNextPage(data.links.next);
setPreviousPage(data.links.previous);
setValid(true);
})
}, [currentPage]);
...
return (
<>
{
...
<PbStart style={style} totalPages={range(1, totalPages 1)} setCurrentPage={setCurrentPage} />
...
}
</>
);
};
const PagItem = ({key, handleClick, className, title, name }) => {
return (
<li key={key} onClick={handleClick}>
<Link to='/' className={className} title={`Go to page ${title}`}>
{name}
</Link>
</li>
);
};
const PbStart = ({ style, totalPages, setCurrentPage }) => {
return (
...
{totalPages.map(p => (
<PagItem key={p} handleClick={() => setCurrentPage(p)} title={p} name={p} />
))}
...
);
};
И в компоненте сообщений я не знаю, как изменить текущую страницу или получить ее из компонента paginaton. Я написал это вот так:
const Softwares = () => {
const [softwares, setSoftwares] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [valid, setValid] = useState(false);
useEffect(() => {
fetch(`http://127.0.0.1:8000/api/software/?p=${currentPage}`)
.then(response => response.json())
.then(data => {
setSoftwares(data.results);
setValid(true);
})
}, [currentPage]);
return (
<>
{
...
{softwares.map(s => (
<Article key={s.id} pathname={s.id} title={s.title} image={s.image} pubdate={s.pub_date} icon={s.category.parent.img} categoryID={s.category.id} categoryName={s.category.name} dCount={s.counter} content={s.content} />
))}
...
}
</>
);
};
Итак, как это сделать(получить текущую страницу из компонента разбиения на страницы или другим способом)?
Комментарии:
1. Я думаю, что работа пейджинатора заключается только в перемещении между страницами и обновлении текущего состояния страницы. Он не должен извлекать данные сам по себе, вы можете предоставить функциональные возможности для дополнительной работы с реквизитами.
Ответ №1:
Я думаю, что работа пейджинатора заключается только в перемещении между страницами и обновлении текущего состояния страницы. Он не должен извлекать данные сам по себе, вы можете предоставить функциональные возможности для дополнительной работы с реквизитами.
Я не проверял это, но это может быть хорошей отправной точкой.
В приведенном ниже примере у вас будет список статей, а затем под ним кнопки «Далее» и «предыдущая».
В Softwares
, как вы можете видеть, я передаю одну и ту же функцию для обработки следующей и предыдущей страниц, вы можете преобразовать ее в одну функцию, например onPageMove
, и вызвать эту функцию handleNext
и handlePrev
. Я добавил две отдельные функции, если вы хотите обрабатывать что-то другое в любом из них.
const Paginator = ({
total, // Required: Total records
startPage = 1, // Start from page / initialize current page to
limit = 30, // items per page
onMoveNext = null, // function to call next page,
onMovePrev = null, // function to call previous page
}) => {
const [currentPage, setCurrentPage] = useState(startPage);
const canGoNext = total >= limit;
const canGoPrev = currentPage > 1;
function handleNext(e) {
if (canGoNext) {
setCurrentPage((prevState) => prevState 1);
onMoveNext amp;amp; onMoveNext({ currentPage });
}
}
function handlePrev(e) {
if (canGoPrev) {
setCurrentPage((prevState) => prevState-1);
onMovePrev amp;amp; onMovePrev({ currentPage });
}
}
return (
<div>
<button onClick={handlePrev} disabled={!canGoPrev}>Prev</button>
<button onClick={handleNext} disabled={!canGoNext}>Next</button>
</div>
);
};
Вот как вы можете использовать пагинатор в других компонентах.
const PER_PAGE = 30; // get max # of records per page
const Softwares = () => {
const [softwares, setSoftwares] = useState([]);
const [valid, setValid] = useState(false);
const onFetchData = ({ currentPage }) => {
fetch(`http://127.0.0.1:8000/api/software/?p=${currentPage}amp;per_page=${PER_PAGE}`)
.then(response => response.json())
.then(data => {
setSoftwares(data.results);
setValid(true);
})
}
useEffect(() => {
onFetchData({ currentPage: 1 })
}, []);
return (
<>
{softwares.map(s => (
<Article key={s.id} pathname={s.id} title={s.title} image={s.image} pubdate={s.pub_date} icon={s.category.parent.img} categoryID={s.category.id} categoryName={s.category.name} dCount={s.counter} content={s.content} />
))}
<Paginator total={softwares.length} limit={PER_PAGE} onMoveNext={onFetchData} onMovePrev={onFetchData} />
</>
);
};