react-dates: Warning: `NaN` is an invalid value for the `height` css style property.

I’m getting the following warnings in a Jest test:

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: `NaN` is an invalid value for the `height` css style property.
        in div (created by DayPicker)
        in div (created by DayPicker)
        in div (created by DayPicker)
        in div (created by OutsideClickHandler)
        in OutsideClickHandler (created by DayPicker)
        in div (created by DayPicker)
        in DayPicker (created by withStyles(DayPicker))
        in withStyles(DayPicker) (created by DayPickerSingleDateController)
        in DayPickerSingleDateController (at DateTimeSelector.js:131)
        in div (created by DateTimeSelector__DayPickerWrapper)
        in DateTimeSelector__DayPickerWrapper (at DateTimeSelector.js:130)
        in div (created by DateTimeSelector__Container)
        in DateTimeSelector__Container (at DateTimeSelector.js:126)
        in DateTimeSelector (created by Connect(DateTimeSelector))
        in Connect(DateTimeSelector) (at OrderPage.js:166)
        in div (created by OrderPage__Container)
        in OrderPage__Container (at OrderPage.js:165)
        in OrderPage (created by Connect(OrderPage))
        in Connect(OrderPage) (at index.js:9)
        in Route (at index.js:5)
        in ProtectedRoute (at PortalApp.js:36)
        in Switch (at PortalApp.js:22)
        in div (at PortalApp.js:20)
        in Router (created by BrowserRouter)
        in BrowserRouter (at PortalApp.js:19)
        in Routes (created by Connect(Routes))
        in Connect(Routes) (at PortalApp.js:85)
        in Provider (at PortalApp.js:84)
        in PortalApp (created by WrapperComponent)
        in WrapperComponent

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.

    Please check the code for the DayPicker component.

I solved that adding the following line to setupTests.js:

jest.spyOn(CalendarMonth.WrappedComponent.prototype, 'setMonthTitleHeight').mockImplementation();

I also get the following:

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: `NaN` is an invalid value for the `width` css style property.
        in div (created by DayPicker)
        in DayPicker (created by withStyles(DayPicker))
        in withStyles(DayPicker) (created by DayPickerSingleDateController)
        in DayPickerSingleDateController (at DateTimeSelector.js:131)
        in div (created by DateTimeSelector__DayPickerWrapper)
        in DateTimeSelector__DayPickerWrapper (at DateTimeSelector.js:130)
        in div (created by DateTimeSelector__Container)
        in DateTimeSelector__Container (at DateTimeSelector.js:126)
        in DateTimeSelector (created by Connect(DateTimeSelector))
        in Connect(DateTimeSelector) (at OrderPage.js:166)
        in div (created by OrderPage__Container)
        in OrderPage__Container (at OrderPage.js:165)
        in OrderPage (created by Connect(OrderPage))
        in Connect(OrderPage) (at index.js:9)
        in Route (at index.js:5)
        in ProtectedRoute (at PortalApp.js:36)
        in Switch (at PortalApp.js:22)
        in div (at PortalApp.js:20)
        in Router (created by BrowserRouter)
        in BrowserRouter (at PortalApp.js:19)
        in Routes (created by Connect(Routes))
        in Connect(Routes) (at PortalApp.js:85)
        in Provider (at PortalApp.js:84)
        in PortalApp (created by WrapperComponent)
        in WrapperComponent

Solved by:

const { componentDidMount } = DayPicker.WrappedComponent.prototype;
jest.spyOn(DayPicker.WrappedComponent.prototype, 'componentDidMount').mockImplementation(
    function mock(...args) {
        const { style } = this.calendarInfo;
        if (!style.marginLeft) style.marginLeft = 0;
        if (!style.marginRight) style.marginRight = 0;
        componentDidMount.apply(this, args);
    },
);

I think that both NaN are generated in calculateDimension https://github.com/airbnb/react-dates/blob/83ec316167b499ce939058973da0aff30e70d178/src/utils/calculateDimension.js#L19 Would be nice to do something like:

if (withMargin) {
  size +=
    parseFloat(style[`margin${axisStart}`] || 0)
    + parseFloat(style[`margin${axisEnd}`] || 0);
}

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 14
  • Comments: 21 (7 by maintainers)

Most upvoted comments

For those who want to remove this error from their tests right now:

Object.defineProperty(window, 'getComputedStyle', {
    value: () => ({
        paddingLeft: 0,
        paddingRight: 0,
        paddingTop: 0,
        paddingBottom: 0,
        marginLeft: 0,
        marginRight: 0,
        marginTop: 0,
        marginBottom: 0,
        borderBottomWidth: 0,
        borderTopWidth: 0,
        borderRightWidth: 0,
        borderLeftWidth: 0
    })
});

@freshollie workaround didn’t work entire for me, since I was using the current getComputedStyle implementation of jsdom, that return a few stuffs (https://github.com/jsdom/jsdom/blob/master/lib/jsdom/browser/Window.js#L643-L671) and default return for getComputedStyle is CSSStyleDeclaration. That way I got the principle of his idea and arrived in this solution:

const originalGetComputedStyle = window.getComputedStyle

const getComputedStyle = (...args) => {
  const cssStyleDeclaration = originalGetComputedStyle(...args)
  cssStyleDeclaration.setProperty('padding-left', 0)
  cssStyleDeclaration.setProperty('padding-right', 0)
  cssStyleDeclaration.setProperty('padding-top', 0)
  cssStyleDeclaration.setProperty('padding-bottom', 0)
  cssStyleDeclaration.setProperty('margin-left', 0)
  cssStyleDeclaration.setProperty('margin-right', 0)
  cssStyleDeclaration.setProperty('margin-top', 0)
  cssStyleDeclaration.setProperty('margin-bottom', 0)
  cssStyleDeclaration.setProperty('border-left-width', 0)
  cssStyleDeclaration.setProperty('border-right-width', 0)
  cssStyleDeclaration.setProperty('border-top-width', 0)
  cssStyleDeclaration.setProperty('border-bottom-width', 0)
  return cssStyleDeclaration
}

Object.defineProperty(window, 'getComputedStyle', {
  value: getComputedStyle,
})

Here’s a typescript version of @renatoagds awesome contribution, using a jest spy that is properly cleaned up in between tests.

let windowSpy: jest.SpyInstance;

beforeEach(() => {
  const originalGetComputedStyle = window.getComputedStyle;

  const getComputedStyle = (...args: any[]) => {
    const cssStyleDeclaration = originalGetComputedStyle(args[0], args[1]);
    cssStyleDeclaration.setProperty('padding-left', '0');
    cssStyleDeclaration.setProperty('padding-right', '0');
    cssStyleDeclaration.setProperty('padding-top', '0');
    cssStyleDeclaration.setProperty('padding-bottom', '0');
    cssStyleDeclaration.setProperty('margin-left', '0');
    cssStyleDeclaration.setProperty('margin-right', '0');
    cssStyleDeclaration.setProperty('margin-top', '0');
    cssStyleDeclaration.setProperty('margin-bottom', '0');
    cssStyleDeclaration.setProperty('border-left-width', '0');
    cssStyleDeclaration.setProperty('border-right-width', '0');
    cssStyleDeclaration.setProperty('border-top-width', '0');
    cssStyleDeclaration.setProperty('border-bottom-width', '0');
    return cssStyleDeclaration;
  };

  windowSpy = jest.spyOn(window, 'getComputedStyle');
  windowSpy.mockImplementation(getComputedStyle);
});

afterEach(() => {
  windowSpy.mockRestore();
});