Material-ui: please provide a class to the component property. The keyboard focus logic needs a reference to work correctly.

Created on 9 Aug 2017  路  29Comments  路  Source: mui-org/material-ui

Problem description

image

Versions

  • Material-UI: v1 beta 4
Button enhancement

Most helpful comment

The warning is gone. Stateless components are supported out of the box.

All 29 comments

That's a warning I have added recently, follow the instruction :).

@oliviertassinari sorry if this is obvious, but I'm new to react and material-ui and am getting the same warnings. I am following the samples in the documentation.
https://material-ui-1dab0.firebaseapp.com/component-demos/lists

Would you mind providing a hint or a link to the relevant set of instructions? Thanks!

@bradrydzewski do you have a reproduction example?

@oliviertassinari I have it as well on beta 5 on a checkbox:

const renderCheckbox = ({ input }) => {
  return <Checkbox value={input.value} onCheck={input.onChange} />
};

I tried setting a few of the props that are defined in the doc, but nothing seems to work.

Thanks for the help!

@Mytrill What's the full example? Ideally you can create a live example on codesandbox.io

Having the same issue. The error is not really clear as to which component is the offending one.

@hassanbazzi Let's see if we can add more information in the warning.

Having the same issue. I was following the instructions and they led me here. Material UI v1 beta 4
Do you have updated instructions?

@kilianc Do you have a reproduction example?

screen shot 2017-08-23 at 10 04 03 pm

:(

screen_shot_2017-08-23_at_9 15 45_pm

Why is this closed? I'm still experiencing it in beta 6.

@dobryanskyy It was closed because the warning was improved. It should be easier to spot the origin of the issue.

@oliviertassinari but how? I just get exact text from images above(and stack trace gives nothing useful). Or will the improvement go to next version?

@dobryanskyy Until we release beta.7 you can replace the warning with a throw. Then you will know exactly where is the issue. Basically, it's coming from a <Button component={Link} where Link is a functional component that can't accept a reference. Use a class instead to implement fix it. One quick hack is to wrap your Link with a withStyles({})(Link) so you expose a class component.

Huh, indeed. I get this when trying to create list with links. Thanks a lot!

Hi @oliviertassinari, I recently upgraded a project from 1.0.0-alpha.22 to 1.0.0-beta.8 and I started seeing this same error in every Jest snapshot test where I have a button. I didn't change anything about the buttons, and I use them in a fairly simple way (without ever setting component):

<IconButton onClick={onPreviewClick} > <EyeIcon data-tip="Show Preview" /> </IconButton>

The docs say that there will be a reasonable default (button), so I am surprised to see this warning. I don't entirely understand what the suggested fix is. I assume we don't need to add component properties to every button. FWIW, I don't get the warnings in the browser console.

Also, I'm not sure the improved error is working. ButtonBase has code for a more detailed error message, but the entirety of the error I ever see is.

Warning: Material-UI: please provide a class to the component property.

The keyboard focus logic needs a reference to work correctly.

It works for me to suppress the warnings in Jest for now, but I thought I'd speak up about seeing these errors.

I don't get the warnings in the browser console

@mcagnew You are right, the warning is still confusion. We should rather say that if user provide a component property, it should be a class component and not a functional component in order to get a ref.
You have most likely written a test that match this case.

@oliviertassinari, yea, I think that would help a lot in making it clearer to people what to do about the error.

To be clear though, I am seeing the warning for all buttons, even ones that do not have a component property explicitly set.

Maybe this is a dumb question but if stateless functional components need to be wrapped in a class component couldn't you do that transparently behind the scenes so the user doesn't have to worry about this?

@pelotom I guess we could try 馃憤

Actually it turns out I _am_ passing a class component to the component property, not a functional component, and still getting this warning. But only in Jest snapshot tests, not in the browser... looks like I'm experiencing the same problem as @mcagnew.

Here's a minimum repro for the Jest snapshot case; it looks specific to react-test-renderer. The warning occurs even with a simple Button with no component property passed:

import * as React from 'react'

import { Button } from 'material-ui'
import * as renderer from 'react-test-renderer'

it('renders correctly', () => {
  renderer.create(
    <Button>Test</Button>
  )
})

This is relevant:
https://facebook.github.io/react/blog/2016/11/16/react-v15.4.0.html#mocking-refs-for-snapshot-testing

With snapshot renderer, this.input will be null because there is no DOM. React 15.4.0 lets us avoid such crashes by passing a custom createNodeMock function to the snapshot renderer in an options argument:

import React from 'react';
import MyInput from './MyInput';
import renderer from 'react-test-renderer';

function createNodeMock(element) {
  if (element.type === 'input') {
    return {
      focus() {},
    };
  }
  return null;
}

it('renders correctly', () => {
  const options = {createNodeMock};
  const tree = renderer.create(<MyInput />, options);
  expect(tree).toMatchSnapshot();
});

It looks like it's necessary to mock refs for snapshot testing with jest. (@pelotom's other suggestion, automatically wrapping non-class components, is still a great idea though)

And here's the fix:
https://github.com/storybooks/storybook/blob/b915b5439786e0edb17d7f5ab404bba9f7919381/examples/test-cra/src/storyshots.test.js#L14-L16

import initStoryshots, { snapshotWithOptions } from '@storybook/addon-storyshots'

initStoryshots({
  ...
  test: snapshotWithOptions({
    createNodeMock: () => ({}),
  }),
})

So the interaction with jest snapshot testing isn't a bug within material-ui. I'll go bother them to more prominently document this quirk and solution.

(And automatic wrapping of non-class components would still be really handy. :)

Thanks @tvald, that at least explains why the behavior is different in Jest. And gives a more reasonable way to suppress those things in Jest runs.

Already 10 participants to this issue. We need to improve the current situation. I'm gonna try @pelotom proposition that @dobryanskyy started.

The warning is gone. Stateless components are supported out of the box.

I am still getting this Warning. I have a NextJS app and I followed the example for that in this repo. There are two ways I can get rid of the warning.

  1. Comment out the @global styles (I have a master HOC similar to withRoot in example).
  2. In my component style, insert html: {}, and body: {}.

Note: It does not seem to matter if the component is stateless or not.
I pulled the example repo and found it does not provide the same warning so I am at a loss at where to look. For now I can comment out the html and body in @global styles and insert that as raw CSS in the _document file but that seems kind of lame.
Any tips on where to look would be awesome. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mb-copart picture mb-copart  路  3Comments

TimoRuetten picture TimoRuetten  路  3Comments

revskill10 picture revskill10  路  3Comments

mattmiddlesworth picture mattmiddlesworth  路  3Comments

FranBran picture FranBran  路  3Comments