为什么在ComponentWillMount中声明的变量未定义?

时间:2019-07-08 14:42:42

标签: javascript reactjs

我有这种类型的组件。为简单起见,我删除了所有不必要的代码。

该组件在单击时会显示一个按钮,应在控制台中显示我在ComponentWillMount中声明的变量的值,但是单击该按钮后,控制台将显示未定义的原因,为什么?

    'use strict';
    class LoginFormComponent extends React.Component {

      handleSubmit() {
        console.log(this.model); //undefined
      }

      componentWillMount() {
        this.model = 123;
      }

      render() {
                    console.log(this.model);  //123
        var styles = this.props.styles;

        return (
                <CM.MUI.FlatButton
                style={styles.buttonStyle}
                onClick={this.handleSubmit}
                label={CM.gettext('Login')}/>
        );
      }
    };

    module.exports = LoginFormComponent;

5 个答案:

答案 0 :(得分:4)

您应该使用componentDidMount来设置实例属性,因为componentWillMount中的内容将不在实例范围内,因为尚未安装组件。

此外,使用=>粗箭头功能可以访问组件的this实例。

更新代码:

class LoginFormComponent extends React.Component {
  handleSubmit = () => {
    console.log(this.model); // 123
  }

  componentDidMount() {
    this.model = 123;
  }

  render() {
    console.log(this.model); //123
    var styles = this.props.styles;

    return (
      <CM.MUI.FlatButton
        style={styles.buttonStyle}
        onClick={this.handleSubmit}
        label={CM.gettext("Login")}
      />
    );
  }
}

export default LoginFormComponent;

控制台

preview

演示:agitated-solomon-3rrow - CodeSandbox

更多信息

如本演示文稿summer-violet-g4pyd - CodeSandbox中所述,React的工作方式如下:

  1. 构造函数
  2. componentWillMount
  3. 渲染
  4. componentDidMount

因此,在执行render()之后,将执行componentDidMount,并且任何状态更改后没有更改

preveiw

如果您希望有东西,请把它们放在constructor()中。

此外,componentWillMount已过时,您不应在以后的版本中使用它。

答案 1 :(得分:2)

由于编写了onClick = {this.handleSubmit},因此您从上下文中分离了该功能,并且在此功能中,您拥有此功能-而不是您的组件 尝试写

onClick = {this.handleSubmit.bind (this)}

handleSubmit = () => {console.log (this.model)}

答案 2 :(得分:1)

componentWillMount中声明的代码将不在实例范围内,原因很简单:该组件尚未挂载。如果要在类中声明全局属性,只需使用componentDidMount或像其他方法一样在类主体中声明它即可。

答案 3 :(得分:1)

首先,model似乎被用作状态字段,如React文档中所述:

  

通常,在React中,构造函数仅用于两个目的:

     
      
  • 通过将一个对象分配给this.state来初始化本地状态。
  •   
  • 将事件处理程序方法绑定到实例。
  •   
     

您不应在构造函数()中调用setState()。相反,如果您的组件需要使用本地状态,请直接在构造函数中将初始状态分配给this.state:

因此,您应该首先使用以下命令定义状态:

constructor(props) {
    this.state.model = 123; // or
    this.state = {          // commonly used syntax
        model : 123
    }
}

然后仍然按照文档进行操作:

  

UNSAFE_componentWillMount()在挂载发生之前被调用。它在render()之前调用,因此在此方法中同步调用setState()不会触发额外的渲染。通常,我们建议使用constructor()代替初始化状态。

您确实使用它来初始化组件的状态。正如其他人指出的那样,您应该使用ComponentDidMount并使用this.setState来修改状态,因为直接用this.state.model修改状态被认为是不良行为

  

构造函数是唯一应直接分配this.state的地方。在所有其他方法中,您需要改用this.setState()。

请检查:https://reactjs.org/docs/react-component.html了解更多信息

答案 4 :(得分:1)

我认为this.modal是指FlatButton组件,您可以将handleSubmit绑定到LoginFormComponent吗?


    class LoginFormComponent extends React.Component {
      constructor(props) {
        super(props);

        // This binding is necessary to make `this` work in the callback
        this.handleSubmit = this.handleSubmit.bind(this);
      }
      handleSubmit() {
      ...