Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't access state inside function in React Function Component

I have the following component in React:

import React, { useState, useEffect } from 'react';
import api from '../../services/api';

const Store = () => {
  const [products, setProducts] = useState([]);
  let pagination = null;

  const getProducts = async (page = 1) => {
    const { data } = await api.get('products', { params: { page } });

    setProducts([...products, ...data.products]);
    pagination = data.pagination;

    if (pagination.current < pagination.max) {
      document.addEventListener('scroll', loadMore);
    }
  };

  const loadMore = () => {
    const { scrollTop, clientHeight, scrollHeight } = document.documentElement;

    if (scrollTop + clientHeight >= scrollHeight - 300) {
      getProducts(pagination.current + 1);
      document.removeEventListener('scroll', loadMore);
    }
  };

  useEffect(() => {
    getProducts();
  }, []);

  useEffect(() => {
    console.log(products);
  }, [products]);

  return (
    <div>
      {products.map(product => (
        <p>{product.name}</p>
      ))}
    </div>
  );
};

export default Store;

My console.log inside the useEffect hook do print the products array correctly, and the component is also rendering the products titles correctly.

But when I try to access the products variable inside the getProducts function it doesn't get the updated products value, it gets the value I have set in the useState hook.

For example, if I start the state with one product, calling products within the getProducts function will always bring this one product, and not the ones loaded from the API fetch, that were correctly logged in the console.

So, when I try to add more products to the end of the array it actually just add the products to an empty array.

Any idea why this is happening? Being able to access the products state inside the useState hook but not inside the getProducts function?

like image 509
Gabriel Castro Avatar asked May 12 '26 09:05

Gabriel Castro


1 Answers

This is happening because the getProducts is using the value products had when getProducts was being declared, not the one products has when the getProducts function is called. This is always the case when you want to access the most recent state directly in non-inline functions. Mostly, you will need to pass the updated value through the function arguments.

But this is not an option in your case. The only option in your case is to use the previous value as the argument from a callback passed to setState (in your case, setProducts).

Hope this helps someone else in future :).

like image 112
Gad Ishimwe Avatar answered May 15 '26 00:05

Gad Ishimwe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!