繁体   English   中英

如何从React中的另一个静态方法调用静态方法?

[英]How to call a static method from another static method in React?

我试图从React组件中的另一个静态方法调用静态方法:

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>
  }
}

现场演示: https//codesandbox.io/s/rmxy909ovo

但是我得到的错误是this是未定义的,即使MDN说

为了在同一个类的另一个静态方法中调用静态方法,可以使用this关键字。

为什么在静态方法中this是未定义的,如何在此示例中调用getDerivedStateFromProps中的方法add

如果使用相应的上下文调用静态方法作为HelloWorld.getDerivedStateFromProps()this将引用getDerivedStateFromProps类构造getDerivedStateFromPropsthis === HelloWorld

getDerivedStateFromProps不是这种情况。 它是一个钩子,它作为类静态方法的目的是将提供的函数与特定组件相关联。 它在没有提供this上下文的情况下被渲染称为回调。 它的设计就是专门用于将它与类实例隔离开来,并防止在遗留生命周期钩子( componentWillReceiveProps等)中常见的可能的误用。

这里真正的问题是add不应该是HelloWorld方法,因为它不属于该类。 由于它无法访问组件实例,因此它只是一个使用该类作为命名空间的函数。 在现代JS中使用类作为命名空间是反模式。 相反,它可能是:

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

class HelloWorld extends React.Component {
  static getDerivedStateFromProps(props, state){
    const sum = add(2, 2);    
    return {
      sum
    }
  }
  ...
}

你从另一个调用静态方法看到下面的代码。

static getDerivedStateFromProps() {
   HelloWorld.add()
}

需要在类而不是实例上访问静态方法。 试试这个:

HelloWorld.add(2,2);

重要更新:这个答案不正确,抱歉。 在发布之前,我应该仔细检查@ChrisG的评论是否正确。 @ estus的答案是正确的答案。

如果您将代码粘贴到Babel游乐场,您可以看到直接调用HelloWorld.getDerivedStateFromProps()确实可以按预期工作,甚至可以编译为ES5。


原始( 不正确 )答案:

(注意,这个答案只是部分不正确;在正常情况下,使用this来调用另一个静态方法确实是有效的语法。)

虽然我个人认为它不像显式使用类名( HelloWorld )那样可读,但您最初发布的代码是有效的,并且MDN是正确的。 正如@ChrisG在他的评论中指出的那样,问题在于它在Babel向ES5转化的代码中不起作用。 如果您更改目标以使其转换为ES6,它应该可以工作,但当然它不适用于不支持ES6的浏览器。

是的,您无法在静态方法中找到此对象。 但是你可以在另一方面实现这个目标。 您可以声明一个全局变量,并将“this object”引用分配给构造函数中的那个。 您可以查看以下代码: -

import React, {Component} from 'react';
var _this;
class Toastr extends Component{
  constructor(props){
    super(props)
    this.state={
      visible: 'hide'
    }
    _this = this
  } 

  static handleShow = (isSuccess, message, code) => {
    _this.setState({visible: 'show', message: message})
    setTimeout( function(){
      _this.setState({visible: 'hide'})
    }, 3000)
  }

  render(){
    return(
      <div aria-live="polite" aria-atomic="true" className="toast-conatiner">
        <div className="toast-position">
           <div className={`toast ${this.state.visible}`} role="alert" aria-live="assertive" aria-atomic="true">
             <div class="toast-body">
                <span className={this.state.isSuccess ? 'text-success' : 'text-danger'}>{this.state.message}</span>
             </div>
           </div>
         </div>
       </div>
     );
   }
 }

 export default Toastr;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM