'Memoized functions to custom hook not picking up updated value from hook

Given a small hook defined as

const useCount = ({ trigger }) => {
  const [count, setCount] = useState(1)
  const increment = () => setCount(count => count + 1);
  return {
    data: count,
    increment,
    trigger,
  }
}

and being consumed as

function App() {
  let data;

  const log = useCallback(() => {
    console.log(data);
  }, [data]);

  const hooked = useCount({
    trigger: log
  });

  ({ data } = hooked);

  const { trigger, increment } = hooked;

  return (
    <div className="App">
      <div>{data}</div>
      <button onClick={increment}>Increment</button>
      <button onClick={trigger}>Log</button>
    </div>
  );
}

If we click on increment, the data is updated. If we click on Log, the memoized value of 1 is logged.

Q1. Is it an anti-pattern to consume data returned by the hook in the memoized callback that is itself passed to the hook?

Q2. Why does it log 1 rather than undefined. If the log fn has picked up 1, why doesn't it pick up subsequent updates?

Q3. Removing the memoization for log fn would make it work. Is there any other apporach to work around this that doesn't involve removing memoization?

A small reproduction is available in this codesandbox.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source