1

I have a component in which I have this useEffect:

  const [charactersInfo, setCharactersInfo] = useState(null);

  const [page, setPage] = useState(1);

  useEffect(() => {
    fetch(`https://api/api/character/?page=${page}`)
      .then((res) => res.json())
      .then((result) => {
        setCharactersInfo(result);
      });
  }, [page]);

whenever my page state updates there is different data coming from the api as expected. but issue is whenever new setCharactersInfo(result) happens, it does not display the new data.

I am passing my setPage state function to this component as a prop:

   <PaginationButtons
          data={charactersInfo}
          updatePage={(number) => {
            setPage(number);
          }}
        />

This is re-usable component which generates buttons and it works correctly everywhere except this specific component. any suggestions please?

import React, { useState, useEffect } from "react";

import "./PaginationButtons.css";

function PaginationButtons({ data, updatePage }) {
  const [buttonsArr, setButtonsArr] = useState([]);

  useEffect(() => {
    const finalArray = [];
    const { info } = data;
    // Not the best solution for situations in which
    // info.pages is big number(e.x 1000000) but since we know that
    // it mostly will be 34 or less so we can just loop through it :)
    for (let i = 1; i < info.pages + 1; i++) {
      finalArray.push(
        <button
          className="page_button"
          onClick={() => updatePage(i)}
          key={Math.random()}
        >
          {i}
        </button>
      );
    }
    setButtonsArr(finalArray);
  }, []);
  return <div className="button_container">{buttonsArr.map((el) => el)}</div>;
}

export default PaginationButtons;

data prop is an object which contains various of stuff and on the them is the number of pages that should be displayed. in this specific case it 34 for so I use state and useEffect to loop through this number and store buttons in the state array and map it afterwards

4
  • Can you update your question to include all relevant code? Can you share PaginationButtons component code? Commented Aug 22, 2021 at 7:27
  • @DrewReese sure just a moment Commented Aug 22, 2021 at 7:28
  • @DrewReese I updated the question with PaginationButtons code Commented Aug 22, 2021 at 7:28
  • I think you are missing data dependency in useEffect of PaginationButtons Commented Aug 22, 2021 at 7:33

3 Answers 3

1

You should handle data change in your child component as well. pass data to useEffect dependency list.

 useEffect(() => {
    const finalArray = [];
    const { info } = data;
    // Not the best solution for situations in which
    // info.pages is big number(e.x 1000000) but since we know that
    // it mostly will be 34 or less so we can just loop through it :)
    for (let i = 1; i < info.pages + 1; i++) {
      finalArray.push(
        <button
          className="page_button"
          onClick={() => updatePage(i)}
          key={Math.random()}
        >
          {i}
        </button>
      );
    }
    setButtonsArr(finalArray);
  }, [data]);

This should help you, no need to maintain state. and i see pages is not array its just key value pair.

function PaginationButtons({ data, updatePage }) {
 const { info : { pages } } = data;
  return (
    <div className="button_container">
       <button
          className="page_button"
          onClick={() => updatePage(pages || 0)}
          key={pages}
        >
          {pages || 0}
        </button>
    </div>
  );
}
Sign up to request clarification or add additional context in comments.

2 Comments

sadly it didn't fix it :(
pls check new ans
1

The useEffect in PaginationButtons is using an empty dependency so it doesn't update when the data prop updates. From what I can tell you don't need the buttonsArr state anyway. It's also anti-pattern to store derived state from props. Just map the data array prop to the buttons.

Using random values is probably the least ideal method of specifying React keys. You can use the mapped array index, but you should use a unique property for each page element, or if there isn't one you should augment the data with a generated GUID.

function PaginationButtons({ data, updatePage }) {
  return (
    <div className="button_container">
      {data.?info?.pages?.map((page, i) => (
        <button
          className="page_button"
          onClick={() => updatePage(i)}
          key={i} // <-- or page.id if available
        >
          {i}
        </button>
      ))}
    </div>
  );
}

1 Comment

data prop is an object which contains various of stuff and on the them is the number of pages that should be displayed. in this specific case it 34 for so I use state and useEffect to loop through this number and store buttons in the state array and map it afterwards
0

As stated in the other answers, you need to add data as a dependency. Also, you don't need to call map on buttonsArr, as you're not doing anything with its elements. Just use buttonsArr itself

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.