How to display posts on the current page from the API Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of How to display posts on the current page from the API without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I’m getting data from Django Rest API and React for Frontend, and I need to create the pagination with posts. I did it all in pagination component. I created the state with current page and I’m changing it by clicking on the page button in component like this:

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

And in posts component I don’t know how to change current page, or getting it from the paginaton component. I’ve written that like this:

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

So, how to do that(get the current page from pagination component or another way)?

Answer

I think a Paginator’s job is only moving between pages and updating current page state. It should not be fetching data by itself, you can provide functionality to do extra work with props.

I haven’t tested this, but this might be a good starting point.

With the example below you’ll have a list of articles and then below it next and previous buttons.

In Softwares, as you can see I am passing the same function for handling next and previous pages, you can refactor it to have one function like onPageMove and call this function handleNext and handlePrev. I added two separate functions if you have want to handle something different in either.

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 && onMoveNext({ currentPage });
    }
  }

  function handlePrev(e) {
    if (canGoPrev) {
      setCurrentPage((prevState) => prevState-1);
      onMovePrev && onMovePrev({ currentPage });
    }
  }

  return (
    <div>
      <button onClick={handlePrev} disabled={!canGoPrev}>Prev</button>
      <button onClick={handleNext} disabled={!canGoNext}>Next</button>
    </div>
  );
};

Here is how you can use Paginator in other components.

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}&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} />
    </>
  );
};
We are here to answer your question about How to display posts on the current page from the API - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji