UseState value doesn't change when re-render in NextJs

I am creating a blog application on NextJs and on the page which displays posts by category i faced with a problem

i have a useState which contains all posts that i get from backend by category that i pass

The problem is when i click on the link which changes category of displayed posts i still got same posts on page, and to get actual useState value i have to reload page, how to fix it?

Here is full component

const News: FC<NewsCat> = ({ news, category }) => {
const [selectedCateg, setSelectedCateg] = useState(category);

//UseState with posts
const [postsList, setPostsList] = useState(news);


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


const handleClick = (categ: string) => {
setSelectedCateg(categ);
};

return (
<div className={styles.wrap}>
  <nav className={styles.categories}>

//Cetegory list

    {list.map((i: string, index) => (
      <Link href={"/category/" + listEng[index]} key={index}>
        <button
          className={styles.active}
          onClick={() => handleClick(listEng[index])}
        >
          <h2>{i}</h2>
        </button>
      </Link>
    ))}
  </nav>
  <div className={styles.catTitle}>
    <h1>{newsTranslate(selectedCateg)}</h1>
  </div>
  <div className={styles.mainBlock}>
    {postsList.map((i: News) => (
      <div key={i._id} className={styles.normal_card}>
        <div className={styles.normal_card_img}>
          <Link href={"/news/" + i._id}>
            <img src={i?.image} alt="" />
          </Link>
          <div className={styles.desc}>
            <div className={styles.up_desc}>
              <Link href={"/category/" + category}>
                <h6>{newsTranslate(i.category)}</h6>
              </Link>
              <h6>| {moment(i.createdAt).format("LLL")}</h6>
            </div>
            <Link href={"/news/" + i._id}>
              <h2 className={styles.titleDesc}>
                {i.title?.length > 150
                  ? `${i.title?.substring(0, 90)}...`
                  : i.title}
              </h2>
            </Link>
          </div>
        </div>
        <div className={styles.normal_card_desc}>
          <h4>{moment(i.createdAt).format("LLL")}</h4>
        </div>
      </div>
    ))}

  </div>
  <div className={styles.loadMoreButton}>
      <button
        onClick={async () => {
          setPage(page + 1);
          console.log(page);

          const getNextPosts = await axios.get(
            "http://localhost:3000/api/category/" + category,
            {
              params: {
                page: page,
              },
            }
          );

          setPostsList([...postsList, ...getNextPosts.data]);
        }}
      >
        LoadMore
      </button>
    </div>
 </div>
 );
};
export default News;
export const getServerSideProps: GetServerSideProps = async ({
  params,
}: any) => {
const res = await axios.get(
`http://localhost:3000/api/category/${params.category}`,
 {
  params: {
    page: 1
  }
 }
 );
return {
props: {
  news: res?.data,
  category: params?.category,
},
};
};

I know that i can fix it like this:

useEffect(() => {
setPostsList(news)
}, [news])

but in my opinion its not the best way

>Solution :

postsList will only change value when you call setPostsList (except for the initial value which you’re passing in on first load).

So after the category is changed, you’ll need to fetch the posts from the API and call setPostsList (similar to how you are doing on page change)

Leave a Reply