15

I want to add some rules for props:

import React, { Component } from 'react'

export default class App extends Component {
  static propTypes = { name: React.PropTypes.string.isRequired };

  render() {
    return(
    )
  }
}

But I got this an error:

Warning: Failed prop type: Required prop `name` was not specified in `App`.

I have this configuration for babel:

{
  "presets": ["es2015", "react"],
  "plugins": ["transform-runtime", "transform-class-properties"]
}

What I did wrong?

Upd. Change code: use static

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Pavel
  • 2,103
  • 4
  • 23
  • 41
  • 1
    Possible duplicate of [ES6 class variable alternatives](http://stackoverflow.com/questions/22528967/es6-class-variable-alternatives) – Dave Newton Jul 13 '16 at 23:20

4 Answers4

20

It appears the you aren't transpiling your code in a way that can recognize static class properties. If you are using babel this can be enabled by using the Class Property Transform : https://babeljs.io/docs/plugins/transform-class-properties/.

In our code base we get this functionality with the Stage 1 preset, https://babeljs.io/docs/plugins/preset-stage-1/

Of course you could always define your proptypes on the class:

export default class App extends Component {
  ...
  render() {
    ...
  } 
}

App.propTypes = {
 data: PropTypes.object.isRequired...
}

^^ this doesn't require any special transpilation.

The in class static property is nice though so you can set it up like this

export default class App extends Component {
  static propTypes = { name: React.PropTypes.string.isRequired };
  render() {...} 
}

rather than define the propTypes on this in the constructor.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
JizoSaves
  • 344
  • 1
  • 11
  • 2
    I turned on this plugin `transform-class-properties`, but still continue to get this error – Pavel Jul 13 '16 at 23:38
  • Changed to use `static` but got this error: `Warning: Failed prop type: Required prop name was not specified in App.` – Pavel Jul 13 '16 at 23:48
  • 2
    So that is good -- you want your `App` to require the prop `name`, it is telling you that you forgot this required prop. Either supply the prop, eg , or remove the isRquired from the propTypes validation. – JizoSaves Jul 13 '16 at 23:53
  • I have run into issues with ReactRouter where although I thought I always supplied a prop, RR would render the component without the prop, so had to remove the `isRequired` designation. – JizoSaves Jul 13 '16 at 23:54
  • Oh, I see, but what if I have `name` in object? `var a = { id: 1, name: 'name', description: 'description11' }` `App data={a} />` – Pavel Jul 13 '16 at 23:58
  • Then you will want to do something like this propTypes = {data: PropTypes.shape({id: PropTypes.number, name: PropTypes. string ...}) Ref: https://facebook.github.io/react/docs/reusable-components.html – JizoSaves Jul 14 '16 at 00:00
  • It appears to be a part of stage-2 at least now. Since that's what I'm using and it works. – Ozymandias Mar 26 '17 at 16:50
4

I'm leaving this answer for the comments but Timothy's answer regarding Babel is better.


In ES6, classes have methods, and that's it--not even properties, let alone static:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static

ES2017 may support a different property mechanism:

https://esdiscuss.org/topic/es7-property-initializers

This question is strongly related to ES6 class variable alternatives and is ultimately probably a dupe.

Community
  • 1
  • 1
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
2

This is ES7 class static property feature.

You can use it with babel-presets-stage-1. Here is the doc http://babeljs.io/docs/plugins/preset-stage-1/ and http://babeljs.io/docs/plugins/transform-class-properties/

If you want to use all features of ES7, you just need install the babel-preset-stage-0.

npm install babel-preset-stage-0 --save-dev

Because stage-0 dependency is stage-1, stage-1 dependency stage-2 and so on. The npm will install all dependencies. So you can use all ES7's feature.

Lin Du
  • 88,126
  • 95
  • 281
  • 483
2

USING BABEL 7

As of babel v7.1.0, to use static class properties as well as properties declared with the property initializer syntax, you need to install a plugin as below:

npm install --save-dev @babel/plugin-proposal-class-properties

Also, all babel's yearly presets were deprecated, so instead of using es2015 simply install and use @babel/preset-env alongside @babel/preset-react. Your babel configuration should look as below:

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": [["@babel/plugin-proposal-class-properties", { "loose": true }],]
}

Read more about the plugin here.

With the above installations and configurations, you can rewrite your component as below:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

export default class App extends Component {
  static propTypes = { name: PropTypes.string.isRequired };

  render() {
    return (
      <div>Static Class Properties</div>
    );
  }
}

And voila it works!!

NOTE: PropTypes is not in react package anymore, you need to import it separately from prop-types package.

Aminu Kano
  • 2,595
  • 1
  • 24
  • 26