-
Notifications
You must be signed in to change notification settings - Fork 47.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default props in ES6 class syntax #3725
Comments
The default props should be already merged in when componentWillReceiveProps is called. |
As far as I can tell, |
That's correct. Instead, you write this: class Control extends React.Component {
// ...
componentWillReceiveProps(props) {
// Do something with props...
}
}
Control.defaultProps = {value: ''}; Does that work for you? |
Ahh, sorry, I see that in the documentation now. Thanks! |
Because I landed here from a Google search, and I prefer the import React, {Component, PropTypes} from 'react'
class DefaultPropsExample extends Component {
static defaultProps = {
...Component.defaultProps,
instructions: 'Usage instructions not provided.',
}
} |
@JHabdas What you have given is not a ES2015 syntax, I guess; Babel throws unexpected token if I use the static props, however, for those guys who work like me in es2015, here's a working stuff. import React from 'react';
export default class extends React.Component {
static get defaultProps() {
return {
// stuff you want :)
}
}
} update After installing @zpao 's link I can use static properties ... |
@Gopikrishna19 you would need to enable another babel plugin that implements the class properties proprosal: http://babeljs.io/docs/plugins/transform-class-properties/ |
@zpao Ooh! Another new stuff today :) will try that, thanks a lot! |
@Gopikrishna19 I actually like the code snippet you posted b/c I can do some pre-processing before initializing the default props. Thanks for mentioning it. |
This seems to be working and it's more elegant in my opinion: ....
static defaultProps = {
//someDefaultProps
};
constructor(props, defaultProps) {
super(props, defaultProps);
}
.... |
@fxhereng The second argument is reserved for |
Ok @gaearon What's the best way to set default props for you? Thanks, |
What's the recommended way to to this? |
If you use the experimental transform http://babeljs.io/docs/plugins/transform-class-properties/, then you can just use
|
Also.. class X extends React.Component {
props = {
...
}
} |
@efernandesng This is not a supported pattern. It won’t behave like |
Seems like I can't get defaultProps to be instantiated with the parent class so that I may pass those props to another child class within. Is there a standard es6 way of doing that? All of the methods on here don't work for me. |
I don’t understand what you mean. Can you show an example? |
Of course, sorry about that. Here is a component:
When I run the webpack-dev-server, I get this error: There must be something I do wrong... |
|
Oh my. Thank you sir. |
no problem @jeanmichelcote! it happens :) |
Accessing other props to define defaultProps is considered an anti-pattern? class Comp extends from React.Component {
static propTypes: {
num: React.PropTypes.number.isRequired,
action: React.PropTypes.func,
};
static defaultProps: {
action: () => console.log(this.props.num), // "this" is invalid in static context
};
render() {
return (
<button onClick={this.props.action}>
{`Log #${this.props.num}`}
</button>
);
}
} |
@romulof it looks like you're trying to reference an instance variable from a static method. You can't do that because there's no way to tell which |
@romulof That's common with all object oriented languages. The fat arrow syntax binds to the context it's defined in. Maybe you could try using
|
@sbussard: Exactly. My question is about |
It is intentionally outside the class so that an optimizing compiler could inline it at the call site. |
So what is the final answer? |
@gaearon you've mentioned that
but does that mean it cannot be optimized when using "class instance fields" and/or "class static fields"? I guess I am trying to understand which approach is preferred and why. |
If you want to stick to ES6, assign it at the bottom: class MyComponent extends Component { /* ... */ }
MyComponent.defaultProps = { /* ... */ }; If you're using Create React App, or if you're comfortable with experimental syntax and have enabled the class properties transform, you can do this: class MyComponent extends Component {
static defaultProps = { /* ... */ };
/* ... */
} These approaches are completely equivalent. Note that if you're also using decorators, you might have weird bugs combining these transforms. So I don't recommend using decorators together with class properties. I hope this helps!
There is no difference between assigning at the end and using class properties. Class properties desugar to assignment. Please use REPL on Babel website to check what code compiles to. |
I am curious about the same issue @romulof talks about. Sure, I can use Why is this useful?I have a generic modal component which has class CreateUserModal extends Modal {
static defaultProps = { title: 'Create a new user' }
} However the What I am trying to do isn't really an anti pattern (or at least I think it isn't) so I wonder if there is another way to do this? I hoped I would be able to do something like class CreateUserModal extends Modal {
constructor (props) {
super({
title: 'Create a new user',
onSubmit: () => {
// do a load of stuff using props
}
})
}
} but it doesn't work. |
@roberttod did you find a solution for your problem? Thanks |
I want to ask a follow up question, class Foo extends Component {
static defaultProps = {};
static propTypes = {};
state = {...};
} what is the difference compare to using constructors to define initial states as: class Foo extends Component {
static defaultProps = {};
static propTypes = {};
constructor(props) {
super(props);
this.state = {...};
}
} specifically is there any performance implications in the first approach? |
It's exactly the same thing, there's no difference. |
@JHabdas Well, so when the defaultProps is defined as:
How to access it from the class methods since:
returns |
@majioa I don't know about that class-level API, but one idea is to cache the default props as a separate object and refer to that. What do you think? |
class Foo extends React.Component {
static defaultProps = { param: 1 };
render() {
return Foo.defaultProps.param;
}
} |
I meet the same problem, you sholud install babel-plugin-transform-class-properties, npm install -D babel-plugin-transform-class-properties then add
|
static get defaultProps() { |
@Arm7107 This is inefficient because it creates a new object every time an element is created. I strongly advise not to use this. Either assign a property: MyComponent.defaultProps = {
// ...
} or use experimental static class properties syntax: class MyComponent extends React.Component {
static defaultProps = {
// ...
};
// ...
} (for which you'll need a Babel plugin) I'll lock this issue to prevent further incorrect suggestions that will show up in Google results. |
The ES6 support announcement says:
This makes a lot of sense to me, but I noticed some small inconsistencies that may be worth rethinking.
When using the original
.createClass
syntax, the value returned bygetDefaultProps
seems to be used at other points in the component lifecycle -- not just in the constructor. For example, if I inspect what gets sent tocomponentWillReceiveProps(props)
, I can see that the default props are applied.This doesn't seem to be the case when using the ES6 class syntax, which means I have to duplicate code. Here's an example of what I mean:
As you can see, I'm duplicating the expression
props.value = props.value || ''
. If I had more than one default, I'd obviously have a lot more duplication.When using the
.createClass
method, I could return{value: ''}
from thegetDefaultProps
method, and this would work, and I'd only have to do it once.Does it make sense to restore this method to avoid unnecessary duplication? Is there another, more React-like approach that I'm not aware of?
The text was updated successfully, but these errors were encountered: