Yanick Rochon
Yanick Rochon

Reputation: 53606

How to access and extend ES7 parent class attributes at declare time in sub-class body?

Considering this class

class BasePage extends Component {
  state = {
    locale: 'en'
  };

  render() {
    return (<div>{ this.state.locale }</div>);
  }
}

How can I declare a sub-class that will also declare a state attribute that will not override the parent class attribute, but will extend it?

class FooPage extends BasePage {
  state = Object.assign( ?super.state, {
    foo: 'Hello'
  });

  render() {
    return (<div>{ this.state.locale } : { this.state.foo }</div>);
  }
}

Obviously, super.state does not work, and BasePage.prototype.state does not exist either.

Is this even possible?

Upvotes: 0

Views: 34

Answers (1)

Mrchief
Mrchief

Reputation: 76248

I'm going to answer it from a plain JS perspective (but same concept applies to React if you're using React).

In order for you to use base's props, you'd need to do so in the child's constructor:

class BasePage {
  state = {
    locale: 'en'
  }; 
}

class FooPage extends BasePage {
  constructor() {
    super();  // can't access this props without calling super first

    // this.state refers to super's state prop. We simply extend it using Object.assign.
    this.state = Object.assign(this.state, {
      foo: 'Hello'
    });
  }  

  render() {
    const { locale, foo } = this.state;
    console.log({ locale, foo });  // prints { locale: 'en', foo: 'Hello' }
  }
}

Demo: https://repl.it/@mrchief/UrbanLiveTrace

Note about React: Since React is built on top of plain JS, the same concepts (i.e. calling super first applies there as well).

Alternatively, if you don't like the constructor approach, you can achieve similar effect via getters:

class BasePage {
  get state()  {
    return { locale: 'en' }
  } 
}

class FooPage extends BasePage {
  get state()  {
    return Object.assign(super.state, {
      foo: 'Hello'
    })
  }  

  render() {
    const { locale, foo } = this.state;
    console.log({ locale, foo });  // prints { locale: 'en', foo: 'Hello' }
  }
}

Demo: https://repl.it/@mrchief/GloriousGainsboroOpensoundsystem

Upvotes: 1

Related Questions