3

Due I refactor my code to ES6, I move all defaults to SomeClass.defaultProps = { ... }.

Suppose a situation, when there is a class hierarchy, and I need to keep some defaults to whole hierarchy. But the problem is that defaultProps not work for classes that are extended:

class AbstractComponent extends React.Component {
  constructor(props) { super(props) }
}
class OneOfImplementations extends AbstractComponent {
  constructor(props) { super(props) }
}
//Problem: hierarchy defaults doesn't work
AbstractComponent.defaultProps = { name: 'Super' } 

Fiddle example

P.S. I'm wondering where is the best place to keep commons (variables/functions) for the whole hierarchy? Maybe do something like this at AbstractComponent:

constructor(props) {
  super(_.assign(props, {
    commonValue: 128,
    commonCallback: _.noop
  }));
}

But the problem is that's become impossible to override one of properties from a subclass

10
  • 1
    I'm pretty sure react recommends avoiding this sort of extending of one's own classes actually Commented Oct 30, 2015 at 10:11
  • @Joshua please explain what you mean. Which sort of extending? Commented Oct 30, 2015 at 10:17
  • This bit class OneOfImplementations extends AbstractComponent { I'm fairly sure I saw spicyj saying should be avoided, i.e. everything should extend React.Component Commented Oct 30, 2015 at 10:18
  • I'm trying to find it, but can't find the github issue Commented Oct 30, 2015 at 10:18
  • What with the ES6 syntax not supporting mixins, abstracting functionality is a bit unknown, but it looks like the @decorator syntax might be the preferred option - github.com/facebook/react/issues/5010 Commented Oct 30, 2015 at 10:20

2 Answers 2

6

Alternatively if you're using the stage: 0 stage: 2 preset in Babel (or the transform directly) you can use es7's proposed static property:

class AbstractComponent extends React.PureComponent {

  static defaultProps = { name: 'Super' }

  // Bonus: you can also set instance properties like this
  state = {
    someState: true,
  }

  // ^ Combined with new arrow binding syntax, you often don't need
  // to override the constructor (for state or .bind(this) reasons)
  onKeyPress = () => {
    // ...
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

unfortunatelly I haven't es7 support
5

It seems like the order of declaration of the "defaultProps" property is important:

class AbstractComponent extends React.Component {
  constructor(props) { super(props) }

  render() {
    return <div>Prop: [ {this.props.name} ]</div>
  }
}
AbstractComponent.defaultProps = { name: 'Super' }

class ComponentImpl1 extends AbstractComponent {
  constructor(props) { super(props) }
}

// works

http://jsfiddle.net/jwm6k66c/103/

2 Comments

thanks! But my case look like this jsfiddle.net/jwm6k66c/104. Because OneOfImplementations is required first, and then require AbstractComponent as dependncy
JS is a scripting language. Order is important. jsfiddle.net/jwm6k66c/2753

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.