Как отображать сообщения на текущей странице из API

#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} />
    </>
  );
};