Search code examples
reactjsreact-hooksconsole.logreact-usememo

React: certain console.log statements skipped in useMemo hook


I'm encountering some weird behavior in a custom React useMemo hook. I'm trying to confirm that the correct values are being returned (as there's some evidence elsewhere that I'm getting the wrong value back), but I can't inspect using a developer console because the code is getting injected in a way that I can't attach to. (Oh well.)

I have a custom hook defined as follows (with all the relevant console.log statements in place for debugging):

const defaultMargins = {...}

export const usePanelDimensions = (width: number, height: number, panelCount: number, panelSpacing: number, margins?: Margins) => {
    return useMemo(() => {
        console.log(`Default margins are ${JSON.stringify(defaultMargins)}`)
        console.log(`Received margins are ${JSON.stringify(margins)}`)
        console.log(`Received width ${width} and height ${height}`)
        const netHorizontalMargin = (margins?.left ?? defaultMargins.left) + (margins?.right ?? defaultMargins.right)
        const netVerticalMargin = (margins?.top ?? defaultMargins.top) + (margins?.bottom ?? defaultMargins.bottom)
        const netPanelSpacing = (panelSpacing * (panelCount - 1))
        console.log(`Net margins: ${netHorizontalMargin} ${netVerticalMargin} ${netPanelSpacing}`)
        const panelWidth = width - netHorizontalMargin
        const panelHeight = (height - netVerticalMargin - netPanelSpacing) / panelCount
        console.log(`-------`)
        console.log(`** panel width ${panelWidth}`)
        console.log(`** should report panel width as ${width - netHorizontalMargin}`)
        console.log(`** Returning panel width ${panelWidth} and panel height ${panelHeight}`)
        console.log(`-----`)
        return {panelWidth, panelHeight}
    }, [width, height, panelCount, panelSpacing, margins])
}

So here we are trying to divide a drawing space into one or more equal-sized bands, offset by some vertical distance.

We receive the overall canvas dimension (read from the rendered component), as well as a number of panels, the space between the panels, and some optional margins. If the margins aren't set, we use some defaults.

We compute the total width of one panel as the input width, less the left and right margins. The height of each panel is the height of the canvas, less the top and bottom margins, then divided into panelCount equal-sized units with panelSpacing pixels between them.

But when I run this, I get output for all the console.log statements except the ones between the dashed lines. Those statements are skipped entirely. Not "the variable interpolation leaves the values out," just the console log doesn't happen at all.

I understand that React sometimes suppresses console logging on second render when StrictMode is on (see https://camunda.com/blog/2021/02/be-careful-with-console-log-when-using-react-strictmode/) but I don't think strict mode is active here.

I considered that the problem might have something to do with some of the values not being set on first render. However, the line ** should report panel width ... is printing a value (width - netHorizontalMargin) which is a direct computation on two values that both get printed successfully a few lines up.

I'm kind of at a loss as to a) why these output statements are getting ignored, and b) how to confirm the value that's actually getting returned, as the hook's consumer also can't display information about these computed values.

Edit

CodeSandbox link: https://codesandbox.io/s/hidden-cdn-0k7chz?file=/src/App.js

Not quite a MWE because obviously there's more code here than there needs to be, but this will show the behavior in question. The code at the CodeSandbox link runs without a problem (printing out the computed values between the --- sections) on Firefox 104.0.1 (Ubuntu snap), where I get output:

Default margins are {"left":30,"right":15,"top":20,"bottom":50}
Received margins are {"left":50,"right":25,"top":30,"bottom":50}
Received width 2700 and height 475
Net margins: 75 80 0
-------
** panel width 2625
** should report panel width as 2625
** Returning panel width 2625 and panel height 395
-----

The issue does reproduce on Chrome 105.0.5195.102 (official Ubuntu 64-bit build), where I see output:

Default margins are {"left":30,"right":15,"top":20,"bottom":50}
Received margins are {"left":50,"right":25,"top":30,"bottom":50}
Received width 2700 and height 475
Net margins: 75 80 0
-------
-----

Before I go filing a bug report against React and/or Chrome, though, has anybody else encountered this behavior or have an explanation for why it might be expected/intended?


Solution

  • Looks like this was down to an old filtering statement in the console. The keywords in question probably shouldn't have impacted these variables, but removing it clears up the problem, so there you are.