Home > Blockchain >  useState is using the wrong value with a custom hook
useState is using the wrong value with a custom hook

Time:12-21

In my React component, I have the following code:

const [additionalGuestAmounts] = useState<RatePlan['additionalGuestAmounts']>(
  useAdditionalGuestAmounts(roomType, occupantsForBaseRate)
)

And here is my custom hook:

const useAdditionalGuestAmounts = (
  roomType: RoomType,
  occupantsForBaseRate: number
): RatePlan['additionalGuestAmounts'] => {
  console.log('executing useAdditionalGuestAmounts hook')
  if (!roomType) {
    return []
  }
  console.log('returning array')
  return [
    {
      foo: 'bar'
    },
  ]
}

When I modify roomType from null to a value, it logs 'executing useAdditionalGuestAmounts hook' and then 'returning array', however the value of additionalGuestAmounts is not updated; it stays as an empty array. Why is the value not being updated if the custom hook is being executed?

CodePudding user response:

The value that is passed in the useState hook is only the initial value of the state as explained on the documentation of the useState hook: https://reactjs.org/docs/hooks-state.html, to make sure that the state is updated whenever the useAdditionalGuestAmounts hook is called we will have to call setAdditionalGuestAmounts with the new value. This would then look like:

    // Initial state
    const [additionalGuestAmounts, setAdditionalGuestAmounts] = useState<RatePlan['additionalGuestAmounts']>([])
    const useAdditionalGuestAmounts = (
        roomType: RoomType,
        occupantsForBaseRate: number
    ) => {
        if (!roomType) {
            return []
        }
 
        // Update the state, this causes the page to re-render
        setAdditionalGuestAmounts( [
            {
                foo: 'bar'
            },
        ])
    }

If you need the useAdditionalGuestAmounts to be called on page load you can use the useEffect hook for this (https://reactjs.org/docs/hooks-effect.html)

CodePudding user response:

The value of the additionalGuestAmounts state variable is not being updated when you modify roomTypeId because the useAdditionalGuestAmounts hook is not being called again. This is because the useAdditionalGuestAmounts hook is only called when the component is first rendered, and is not called again.

As stated previously by rowan, you can a useEffect hook inside the useAdditionalGuestAmounts hook.

const useAdditionalGuestAmounts = (
  roomType: RoomType,
  occupantsForBaseRate: number
): RatePlan['additionalGuestAmounts'] => {
  console.log('executing useAdditionalGuestAmounts hook')
  const [additionalGuestAmounts, setAdditionalGuestAmounts] = useState<
    RatePlan['additionalGuestAmounts']
  >([]);

  useEffect(() => {
    if (!roomType) {
      return;
    }
    console.log('returning array');
    setAdditionalGuestAmounts([
      {
        foo: 'bar',
      },
      {
        foo: 'bar',
      },
      {
        foo: 'bar',
      },
      {
        foo: 'bar',
      },
      {
        foo: 'bar',
      },
    ]);
  }, [roomTypeId, occupantsForBaseRate]);

  return additionalGuestAmounts;
};

You also need to add the occupantsForBaseRate argument to the dependencies array, because the useAdditionalGuestAmounts hook depends on it.

Hope this helps.

  • Related