当前位置: 首页 > 面试题库 >

ReactJS中“ this”之谜

宰子琪
2023-03-14
问题内容

我对Facebook的React世界还很陌生。他们的文档似乎非常好,但是在某些方面我需要一点点澄清。这就是其中之一。

Src:http://tuts-javascript.appspot.com/reactjs-add-remove-table-row

    var CompanyApp = React.createClass({
    getInitialState: function() {
      return {companylist:this.props.companies};
    },
    handleNewRowSubmit: function( newcompany ) {
      this.setState( {companylist: this.state.companylist.concat([newcompany])} );
    },
    handleCompanyRemove: function( company ) {

      var index = -1;   
      var clength = this.state.companylist.length;
        for( var i = 0; i < clength; i++ ) {
            if( this.state.companylist[i].cname === company.cname ) {
                index = i;
                break;
            }
        }
        this.state.companylist.splice( index, 1 );  
        this.setState( {companylist: this.state.companylist} );
    },
    render: function() {
      var tableStyle = {width: '100%'};
      var leftTdStyle = {width: '50%',padding:'20px',verticalAlign: 'top'};
      var rightTdStyle = {width: '50%',padding:'20px',verticalAlign: 'top'};
      return ( 
        <table style={tableStyle}>
          <tr>
            <td style={leftTdStyle}>
              <CompanyList clist={this.state.companylist}  onCompanyRemove={this.handleCompanyRemove}/>
            </td>
            <td style={rightTdStyle}>
              <NewRow onRowSubmit={this.handleNewRowSubmit}/>
            </td>
          </tr>
      </table>
      );
    }
  });

  var CompanyList = React.createClass({
    handleCompanyRemove: function(company){
      this.props.onCompanyRemove( company );
    },
    render: function() {
      var companies = [];
      var that = this; // TODO: Needs to find out why that = this made it work; Was getting error that onCompanyDelete is not undefined
      this.props.clist.forEach(function(company) {
        companies.push(<Company company={company} onCompanyDelete={that.handleCompanyRemove} /> );
      });
      return ( 
        <div>
          <h3>List of Companies</h3>
          <table className="table table-striped">
            <thead><tr><th>Company Name</th><th>Employees</th><th>Head Office</th><th>Action</th></tr></thead>
            <tbody>{companies}</tbody>
          </table>
        </div>
        );
    }
  });

  var Company = React.createClass({
    handleRemoveCompany: function() {
      this.props.onCompanyDelete( this.props.company );
      return false;
    },
    render: function() {
      return (
        <tr>
          <td>{this.props.company.cname}</td>
          <td>{this.props.company.ecount}</td>
          <td>{this.props.company.hoffice}</td>
          <td><input type="button"  className="btn btn-primary" value="Remove" onClick={this.handleRemoveCompany}/></td>
        </tr>
        );
    }
  });

  var NewRow = React.createClass({
    handleSubmit: function() {
      var cname = this.refs.cname.getDOMNode().value;
      var ecount = this.refs.ecount.getDOMNode().value;
      var hoffice = this.refs.hoffice.getDOMNode().value;
      var newrow = {cname: cname, ecount: ecount, hoffice: hoffice };
      this.props.onRowSubmit( newrow );

      this.refs.cname.getDOMNode().value = '';
      this.refs.ecount.getDOMNode().value = '';
      this.refs.hoffice.getDOMNode().value = '';
      return false;
    },
    render: function() {
      var inputStyle = {padding:'12px'}
      return ( 
        <div className="well">
          <h3>Add A Company</h3>
        <form onSubmit={this.handleSubmit}>
          <div className="input-group input-group-lg" style={inputStyle}>
            <input type="text"  className="form-control col-md-8"  placeholder="Company Name" ref="cname"/>
          </div>
          <div className="input-group input-group-lg" style={inputStyle}>
            <input type="text"  className="form-control col-md-8" placeholder="Employee Count" ref="ecount"/>
          </div>
          <div className="input-group input-group-lg" style={inputStyle}>
            <input type="text"  className="form-control col-md-8" placeholder="Headoffice" ref="hoffice"/>
          </div>
          <div className="input-group input-group-lg" style={inputStyle}>
            <input type="submit"  className="btn btn-primary" value="Add Company"/>
          </div>
        </form>
        </div>
        );
    }
  });
  var defCompanies = [{cname:"Infosys Technologies",ecount:150000,hoffice:"Bangalore"},{cname:"TCS",ecount:140000,hoffice:"Mumbai"}];
  React.renderComponent( <CompanyApp companies={defCompanies}/>, document.getElementById( "companyApp" ) );

这是关于ReactJS如何工作的很好的基本解释。感谢作者。

但是这个评论

var that = this; // TODO:需要找出原因,这使它起作用;正在收到错误,指出onCompanyDelete不是未定义的

为什么有必要?这是正确的方法吗?如果没有,那是什么?

提前致谢。


问题答案:

对于ReactJS,没有“ this”这个谜。

这只是标准范围界定问题的一种情况,这些问题随着JavaScript中的回调而出现。

当您处于React this组件中时,就像其他任何JavaScript“类”一样,基本组件上的所有方法都将以当前组件为范围。

在您的代码段中,您有一个render方法,该方法是基本组件上的函数,因此this与组件本身相同。但是,在该render方法中,您要使用调用回调this.props.clist.forEach,方法中的任何函数回调render都需要绑定到正确的this作用域,或者可以这样做var that = this(尽管这是一种反模式,因此不建议使用)。

例如,您的代码片段的简化版本:

var MyComponent = React.createClass({
    handleCompanyRemove: function(e) {
        // ...
    },
    render: function() {
        // this === MyComponent within this scope

        this.props.someArray.forEach(function(item) {
            // this !== MyComponent, therefore this.handleCompanyRemove cannot
            // be called!
        })
    }
})

从上面的注释中可以看出,如果没有在外部定义变量或正确绑定函数,.forEach则无法this直接使用for的回调。

解决此问题的其他选项是:

*将回调函数 *绑定 到正确的此范围。例:

this.props.someArray.forEach(function(item) {
    // this === MyComponent within this scope too now!
    // so you can call this.handleCompanyRemove with no problem
 }.bind(this))

如果使用的是Babel / ES6,则可以使用 Fat Arrow 函数语法,该语法可确保this作用域继续从父作用域继续进行回调。例:

this.props.someArray.forEach((item) => {
    // this === MyComponent within this scope too now!
    // so you can call this.handleCompanyRemove with no problem
})


 类似资料:
  • 问题内容: 我正在遵循一个教程来更新ReactJS中的状态。我在本教程中碰到了这一行,但我不知道发生了什么。我了解此基本知识并进行绑定,但我从未见过如此做过。有人可以解释一下吗?完整代码: 问题答案: 诸如事件之类的DOM回调会将上下文设置为DOM元素本身,在本例中为。尝试删除您不了解的部分,然后看看会发生什么- 您会看到类似的内容,因为该功能未在元素的上下文中定义(基本上是在寻找)。 什么是在该

  • 问题内容: 我正在尝试将方法传递给子组件以处理onclick事件。我在网上看到了很多示例,但无法正常运行。当我在父级的渲染功能中并尝试将“ this.handleClick”传递给子级时,handleClick是未定义的。 看一下ThumbList的渲染方法: 知道我可能会缺少什么吗? 问题答案: 如果您在开发工作流程中使用Babel之类的编译器,则建议使用箭头函数: 如您所见,这是一个很好的紧凑

  • 问题内容: 我正在使用Reactjs,编写一个菜单组件。 每当我在map函数内部使用“ this”时,它都是未定义的,但在外部,则没有问题。 错误: “无法读取未定义的属性’props’” 有人帮我!:(( 问题答案: 需要第二个参数来设置在映射函数中引用的内容,因此将其作为第二个参数传递以保留当前上下文: 另外,您可以使用ES6 箭头功能自动保留当前上下文:

  • 寻求澄清“此”在本上下文中的含义。为什么我需要在ajax请求之后将“this”绑定到回调?当我检查调试器时,不管我是否调用bind,它都会说'this'绑定到构造函数。

  • 问题内容: 例如,我有一个带有两种绑定方法的react组件: 在上面的代码中,我有两种绑定方法:一种是和一种是。功能有效,但无效。运行时,它返回错误: TypeError:无法读取未定义的属性“ handleRemoveComment” 问题答案: 问题在于这条线: 因为您忘记了绑定,映射回调方法,所以inside 方法将不会引用类上下文。 使用这些解决方案中的 任何一种 ,它将起作用。 1- 在

  • 本文向大家介绍详谈jQuery中的this和$(this),包括了详谈jQuery中的this和$(this)的使用技巧和注意事项,需要的朋友参考一下 网上有很多关于jQuery的this和$(this)的介绍,大多数只是理清了this和$(this)的指向,其实它是有应用场所的,不能一概而论在jQuery调用成员函数时,this就是指向dom对象。 $(this)指向jQuery对象是无可厚非的