Material-components-web: Error in mdc-ripple in test environment when using react.js

Created on 20 Jan 2018  路  4Comments  路  Source: material-components/material-components-web

When using ripple in an react.js component I get the following error message when running a test with jest:
TypeError: Cannot use 'in' operator to search for 'mdcRippleIsUnbounded' in undefined

It looks like the error is here:
https://github.com/material-components/material-components-web/blob/e9f02eda9f4343913b99e11b5292ae9532c0c40c/packages/mdc-ripple/index.js#L122

The in-operator is used without checking if this.root_.dataset exists.
Changing the line to:

this.unbounded = this.root_.dataset ? 'mdcRippleIsUnbounded' in this.root_.dataset : undefined;

Solves the problem.

How to reproduce

Create react component.

import React, {Component} from 'react';
import {MDCRipple} from '@material/ripple/dist/mdc.ripple'

import '@material/button/dist/mdc.button.min.css';

class Contact extends Component {

  attachRipple(btn) {
    if (btn) {
      this.ripple = MDCRipple.attachTo(btn, {mdcRippleIsUnbounded: false});
    }
  }

  componentDidMount() {
    this.attachRipple(this.btn)
  }

  render() {
    return (
      <div className="Contact">
        ...
        <button onClick={this.props.openWindow}
                      className="mdc-button mdc-button--raised"
                      ref={btn => {
                        this.btn = btn;
                      }}
         >
            Text
         </button>
    </div>
  )
}

Run test with jest:

it('renders without crashing', () => {
  const div = document.createElement('div');
  ReactDOM.render(<Contact/>, div);
});

All 4 comments

This is fixed in a later version of jsdom. I'm assuming you're using create-react-app which ships with an older version of jest/jsdom. For now you can simply mock out the ripple code:

jest.mock("@material/ripple/dist/mdc.ripple");

Another solution until CRA updates jest/jsdom is to polyfill element dataset support.

npm install --save-dev element-dataset

And then create src/setupTests.js that looks like this:

import elementDatasetPolyfill from "element-dataset";

elementDatasetPolyfill();

HTH.

It seems like you're using the vanilla JS MDCRipple component within a React app, but our vanilla JS components were meant to be used only within vanilla JS apps (or with frameworks that execute within the context of a browser). For apps using frameworks like React, which target more than just the browser, you can use one of the libraries in the README that integrate with different frameworks (for React, you can use RMWC: React Material Web Components).

Also if you'd like to better understand how MDC Web is integrated into other frameworks or build your own MDC Web library, see here.

I got this error in Next.js with

import TopAppBar, { TopAppBarFixedAdjust } from "@material/react-top-app-bar";
import MaterialIcon from "@material/react-material-icon";
import "@material/react-top-app-bar/dist/top-app-bar.css";
import "@material/react-material-icon/dist/material-icon.css";

and couldn't figure out what was wrong :/

Just leaving it here to have other people maybe notice it or tell if they have found a solution

Was this page helpful?
0 / 5 - 0 ratings

Related issues

broros picture broros  路  3Comments

robzenn92 picture robzenn92  路  4Comments

ronnieroyston picture ronnieroyston  路  3Comments

cintaccs picture cintaccs  路  3Comments

kimurakenshi picture kimurakenshi  路  3Comments