1

I have this javascript file which is containing styles in an object for a React app:

const styles = {
  fonts: {
    Georgia: 'Georgia, \'Times New Roman\', Times, serif',
  },
  App: {
    textAlign: 'center',
    fontFamily: this.fonts.Georgia,
  },
};

module.exports = styles;

fontFamily: this.fonts.Georgia would reference App: { fonts: '' } object, but what I want to do is to access the already defined fonts object inside styles. How can I do that?

What works is:

const fonts = {
  Georgia: 'Georgia, \'Times New Roman\', Times, serif',
};

const styles = {
  App: {
    textAlign: 'center',
    fontFamily: fonts.Georgia,
  },
};

module.exports = styles;

This is works in this case, but the upper solution would be much nicer.

Lanti
  • 2,299
  • 2
  • 36
  • 69

2 Answers2

3

Simply speaking, you can't. JavaScript objects have no notion of parentage.

const App = {
  textAlign: 'center',
  fontFamily: this.fonts.Georgia, // ???
}

What does this means in that context?

Moreover

const styles = {
  fonts: 'Georgia, \'Times New Roman\', Times, serif',
  App
};

This is the same object as the first one you've posted.

Your only choice is to split the two objects as you have. To hide this detail away from outside of the module, you can do the following:

module.exports = {fonts, styles};

That will make it so that both the fonts and the styles are available to the outside. You can mix and match to get the exact object you want, but the actual structure is irrelevant for the question.

Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • Sorry to hear that, thank you for the clarification. Later on there will be more fonts and I wanted to store the entire stylesheet under the same variable, but looks like this is not possible if I want to reference things inside the same parent variable. – Lanti Sep 18 '16 at 13:52
  • 2
    You could hold a reference to `styles` inside of `App` (you'll still need to define them separately), and once you do that, you will be able to access it with something like `this.styles`, of course, it allows for circular references (`this.styles.App.styles.App.styles....`), so be careful when recursively iterating. – Madara's Ghost Sep 18 '16 at 13:54
1

An approach that works is using a getter to retrieve the fonts property dynamically.

const styles = {
  fonts: {
    Georgia: 'Georgia, \'Times New Roman\', Times, serif',
  },
  App: {
    textAlign: 'center',
    get fontFamily () { return styles.fonts.Georgia },
  },
};

console.log(styles);

Note that this has some drawbacks:

  • The App.fontFamily property will always mirror fonts if it changes dynamically. This may or may not be the desired behavior.
  • Without a setter, App.fontFamily can only be get, not set.
  • Some serializers may not process objects with non-value properties as one would expect. I guess this is true for some other libraries, too.
GOTO 0
  • 42,323
  • 22
  • 125
  • 158
  • Is there any performance hit using `get` inside objects? If I start to treat inline styles in React like Sass or Stylus stylesheets, I will cross-reference in an object a lot with `get`. – Lanti Sep 18 '16 at 15:57
  • 1
    Yes, but I suspect the impact should be negligible, even with a lot of objects. For me, with this code, maintainability would be the biggest concern (because of the reasons above). – GOTO 0 Sep 18 '16 at 18:15