1

The following components will yield the same result:

const currYear = Date.now().getFullYear();

class App extends React.Component {
  render() {
    return <MyComponent year={currYear} />;
  }
};

class App extends React.Component {
  constructor() {
    super();
    this.currYear = Date.now().getFullYear();
  }

  render() {
    return <MyComponent year={this.currYear} />;
  }
};

Assume the variable never changes.

Can their application be considered equivalent?
If not, are there situations where one should prefer the one method over the other?

Been curious for a long time, but never found a solid answer.

2
  • In the fist case, the currYear will be evaluated as your code is interpreted. In the second case, currYear will not be evaulated unless until some part of app executes new App() Commented Aug 1, 2018 at 9:37
  • So, No they are not exactly equivalent. For example, imagine that the code was interpreted a few milliseconds before the new year and then the new App() was called yielding different date! I'd personally go with the 2nd approach Commented Aug 1, 2018 at 9:41

5 Answers 5

1

In this particular case they are equivalent, primarily because App is supposed to be instantiated once.

This wouldn't be true for a component that is instantiated multiple times. If a user changes system time or a new year comes in, this.currYear changes in future component instances, too.

Using constants as class fields provides more flexibility. There may be a need to change them during tests, this may improve testability. And can be changed in child classes when needed. Even if you didn't design the class to be extendable, another developer may benefit from extensibility:

class BackToTheFutureApp extends App {
  currYear = 1955;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Good answer. The class field currYear = 1955 transpiles in babel into this.currYear = 1955 anyway, doesn't it? So why does it provide more flexibility? Other than that, it is my understanding that my examples are equivalent except if the same component is used more than once in which case this.currYear is re-set every new instance, which is not the case in the first example. Correct?
Yes, that's correct. It provides more flexibility because this.currYear can be set to something else in child classes (or even be patched in App with some hacking, e.g. for testing), while currYear can't. Using 1955 instead of currYear constant would require to override entire render method.
0

The first component defines a global javascript variable which could clash with something else (third party components or scripts that may be present). If another component or script also defines this variable you will get a run-time error. If this is the only instance in the whole application (including any other components you use) then it will be no issue. Still, it is somehow cleaner not to define global variables.

2 Comments

While I can agree that using instance variables "seems" cleaner and safer, I can't see an actual scenario where the first example would actually be problematic since we are working with React (js modules, encapsulation, etc).
What did make you think that it defines a global? If this code was be evaluated in global scope, App would be a global, too. Fortunately, they are not and likely have module scope.
0

Inside of your constructor means that for each instance of your component you'll also have an instance of that variable. I'd imagine you'd be better of using it as per your first example because that will create just one variable no matter how many instances of your component their are. It's also worth noting though that if you take this approach and your program is running for more than a year that it may at some point be incorrect.

Comments

0

first let us answer following question. By answering which we make correct choice. Will currYear variable be used by other components other than App if no then it should be implemented inside App Component. Why you may ask: 1.For code readability by other developers. 2.To make it obvious that currYear is used only by App component and no any other component. 3.To prevent accidental change.

1 Comment

I only ever write one component per file. As such, I don't think anyone can be confused about where it's used. I also don't think either approach is more readable than the other, nor more prone to mistakes.
0

In the first case:

const currYear = Date.now().getFullYear(); // Date is created here

class App extends React.Component {
  render() {
    return <MyComponent year={currYear} />;
  }
};

currYear is the date when the file was required from other file or included on page. While on second example you declare currYear when the instance of the class is created, so dates will be different:

class App extends React.Component {
  constructor() {
    super();
    this.currYear = Date.now().getFullYear();
  }

  render() {
    return <MyComponent year={this.currYear} />;
  }
};

<App/> // Date is created here

Also the first pattern is very bad in almost all cases, for example if you do currYear.setDate(...) variable value will change in every class without re-rendering view.

5 Comments

Thanks for your answer. Your last sentence is moot though, because we assumed that the variable never changes... ever. Besides, doing setDate() in the 2nd example also won't re-render anything.
@Chris in the second example you can place it in state and call setState, you can't do it in first example.
@Chris The most important thing to note is that in second example you may get different dates on each created instance of App.
I realize that, but please consider the examples provided "as they are". We are not considering moving or changing anything.
You realize that you will get different dates on each component usage in second example right? If so, and if you want to have static currDate, place it inside component class like static currYear = Date.now().getFullYear()

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.