How can I recognize the value directly in useCallback?

I want to run console.log(‘success’) when myFood[myFood.length – 1]?.id and viewable Items[viewable Items.length – 1]?.item?.id are equal.

But for example, console.log(‘success)’ is not executed even though both values ​​match.

There seems to be some problem getting the value of myFood[myFood.length – 1]?.id. How do I fix the code?

     myFood = [

0: {id: 16, name: "13", content1: "1", content2: "2", content3: "3", …}
1: {id: 15, name: "12", content1: "1", content2: "2", content3: "3", …}
2: {id: 14, name: "11", content1: "1", content2: "2", content3: "3", …}
3: {id: 13, name: "10", content1: "1", content2: "2", content3: "3", …}
4: {id: 12, name: "9", content1: "1", content2: "2", content3: "3", …}
5: {id: 11, name: "8", content1: "1", content2: "2", content3: "3", …}
6: {id: 10, name: "7", content1: "1", content2: "2", content3: "3", …}
7: {id: 9, name: "6", content1: "1", content2: "2", content3: "3", …}
8: {id: 8, name: "5", content1: "1", content2: "2", content3: "3", …}   
9: {id: 7, name: "4", content1: "1", content2: "2", content3: "3", …}
             ]

this is my code

    const {myFood, loaduserhasMorePosts, loadPostsLoading} = useSelector(
      (state) => state.post,
    );

    myFood[myFood.length - 1]?.id; //7

    
    const onViewableItemsChanged = useCallback(
      async ({viewableItems}) => {
        if (
          myFood[myFood.length - 1]?.id ===
          viewableItems[viewableItems.length - 1]?.item?.id //7
        ) {
          console.log('success');
        }
      },
      [hey, myFood],
    )
        return (
        <>
          <FlatList
            viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs.current}
  
            data={myFood}
          
          />
        </>
      );

Answer

It seems like you are expecting the first argument to useCallback to be executed and therefore logging to the console:

const onViewableItemsChanged = useCallback(
  async ({viewableItems}) => {
    if (
      myFood[myFood.length - 1]?.id ===
      viewableItems[viewableItems.length - 1]?.item?.id //7
    ) {
      console.log('success');
    }
  },
  [hey, myFood],
)

The useCallback method creates a memoized callback, it does not execute the method you are passing to it. As explained in the documentation, useCallback is just a special case of useMemo, which returns a memoized value.

const str = 'foo';
const fn = () => str;
const deps = [str];
const callback1 = useCallback(fn, deps); // equivalent to callback2
const callback2 = useMemo(() => fn, deps); // equivalent to callback1

If you are not familiar with memoization, wikipedia has a good explanation. I also noticed that in your code:

  1. hey is undefined
  2. hey is never used in the callback that you are passing in the first argument to useCallback

The documentation for useCallback mention the following:

The array of dependencies is not passed as arguments to the callback. Conceptually, though, that’s what they represent: every value referenced inside the callback should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically.

Including it in the dependencies will cause the memoized value to be recomputed more than necessary.