Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a static method from another static method in React?

I am trying to call a static method from within another static method in a React component:

class HelloWorld extends React.Component {

  static add(a, b){
    return a + b;
  }

  static getDerivedStateFromProps(props, state){
    const sum = this.add(2, 2);    
    return {
      sum
    }
  }

  render() {
    return <div>Hello World</div>
  }
}

Live demo: https://codesandbox.io/s/rmxy909ovo

But I get the error that this is undefined, even though MDN says:

In order to call a static method within another static method of the same class, you can use the this keyword.

Why is this in a static method undefined and how to call the method add within getDerivedStateFromProps in this example?

like image 347
Sebastian Avatar asked Oct 17 '18 11:10

Sebastian


3 Answers

If static method is called with respective context as HelloWorld.getDerivedStateFromProps(), this will refer to class constructor inside getDerivedStateFromProps, this === HelloWorld.

This is not the case for getDerivedStateFromProps. It is a hook, its purpose as class static method is to associate provided function with specific component. It's called as a callback by the render without this context provided. It was designed like that specifically to isolate it from class instance and prevent possible misuses that are common in legacy lifecycle hooks (componentWillReceiveProps, etc).

The real problem here is that add shouldn't be HelloWorld method because it doesn't belong to the class. Since it cannot access component instance, it's only a function that uses the class as a namespace. Using classes as namespaces is antipattern in modern JS. Instead, it could be:

function add(a, b){
  return a + b;
}

class HelloWorld extends React.Component {
  static getDerivedStateFromProps(props, state){
    const sum = add(2, 2);    
    return {
      sum
    }
  }
  ...
}
like image 94
Estus Flask Avatar answered Oct 20 '22 21:10

Estus Flask


A static method needs to be accessed on the class not an instance. So try this:

HelloWorld.add(2,2);
like image 22
OttO Avatar answered Oct 20 '22 23:10

OttO


IMPORTANT UPDATE: This answer is incorrect, sorry. I should have double-checked that @ChrisG's comment was correct before posting it. @estus's answer is the correct answer.

If you paste your code into the Babel playground you can see that calling HelloWorld.getDerivedStateFromProps() directly indeed works as you intended, even compiling to ES5.


Original (incorrect) answer:

(Note that this answer is only partially incorrect; using this to call one static method from another is indeed valid syntax in normal circumstances.)

While I personally don't find it as readable as using the class name (HelloWorld) explicitly, the code you originally posted is valid, and MDN is correct. As @ChrisG pointed out in his comment, the problem is that it doesn't work in code transpiled by Babel to ES5. If you change the target so it transpiles to ES6, it should work, although of course it won't work in browsers that don't support ES6.

like image 2
Matt Browne Avatar answered Oct 20 '22 22:10

Matt Browne