“这个"之谜在 ReactJS 中

编程入门 行业动态 更新时间:2024-10-27 22:19:48
本文介绍了“这个"之谜在 ReactJS 中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我对 Facebook 的 React 世界还很陌生.他们的文档似乎非常好,但有几个方面我需要澄清一下.这是其中之一.

源:tuts-javascript.appspot/reactjs-add-remove-table-row

var CompanyApp = React.createClass({getInitialState:函数(){返回 {companylist:this.propspanies};},handleNewRowSubmit:函数(新公司){this.setState( {companylist: this.statepanylist.concat([newcompany])} );},handleCompanyRemove:函数(公司){无功指数 = -1;var clength = this.statepanylist.length;for( var i = 0; i < clength; i++ ) {if( this.statepanylist[i]ame === companyame ) {指数 = i;休息;}}this.statepanylist.splice( index, 1 );this.setState( {companylist: this.statepanylist} );},渲染:函数(){var tableStyle = {width: '100%'};var leftTdStyle = {width: '50%',padding:'20px',verticalAlign: 'top'};var rightTdStyle = {width: '50%',padding:'20px',verticalAlign: 'top'};返回 (<table style={tableStyle}><tr><td style={leftTdStyle}><CompanyList clist={this.statepanylist} onCompanyRemove={this.handleCompanyRemove}/></td><td style={rightTdStyle}><NewRow onRowSubmit={this.handleNewRowSubmit}/></td></tr>);}});var CompanyList = React.createClass({handleCompanyRemove:函数(公司){this.props.onCompanyRemove(公司);},渲染:函数(){var 公司 = [];var that = this;//TODO:需要找出原因 = 这使它起作用;收到 onCompanyDelete 不是未定义的错误this.props.clist.forEach(function(company) {company.push(<Company company={company} onCompanyDelete={that.handleCompanyRemove}/>);});返回 (<div><h3>公司名单</h3><table className="table table-striped"><thead><tr><th>公司名称</th><th>员工</th><th>总公司</th><th>行动</th></tr>;</thead><tbody>{公司}</tbody>

);}});var 公司 = React.createClass({handleRemoveCompany:函数(){this.props.onCompanyDelete( this.propspany );返回假;},渲染:函数(){返回 (<tr><td>{this.propspanyame}</td><td>{this.propspany.ecount}</td><td>{this.propspany.hoffice}</td><td><输入类型=按钮"className =btn btn-primary";值=删除"onClick={this.handleRemoveCompany}/></td></tr>);}});var NewRow = React.createClass({句柄提交:函数(){var cname = this.refsame.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.refsame.getDOMNode().value = '';this.refs.ecount.getDOMNode().value = '';this.refs.hoffice.getDOMNode().value = '';返回假;},渲染:函数(){var inputStyle = {padding:'12px'}返回 (<div className=好"><h3>添加一个公司</h3><form onSubmit={this.handleSubmit}><div className="input-group input-group-lg";样式={输入样式}>

<div className="input-group input-group-lg";样式={输入样式}>

<div className="input-group input-group-lg";样式={输入样式}>

<div className="input-group input-group-lg";样式={输入样式}>

</表单>

);}});var defCompanies = [{cname:"Infosys Technologies",ecount:150000,hoffice:"Bangalore"},{cname:"TCS",ecount:140000,hoffice:"Mumbai"}];React.renderComponent( <CompanyApp Companies={defCompanys}/>, document.getElementById( "companyApp" ) );

这是对 ReactJS 工作原理的非常好的基本解释.感谢作者.

但是这个评论,

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

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

提前致谢.

解决方案

ReactJS 特有的这个"并不神秘.

这只是 JavaScript 回调中出现的标准范围问题的一个例子.

当您在 React 组件中时,基础组件上的所有方法都将被限定为 this 作为当前组件,就像任何其他 JavaScript类"一样.

在您的代码片段中,您有一个 render 方法,它是基础组件上的一个函数,因此 this 等于组件本身.但是,在该渲染方法中,您使用 this.props.clist.forEach 调用回调,render 方法内的任何函数回调都需要绑定到正确的this 作用域,或者你可以做 var that = this(虽然这是一种反模式,应该被阻止)`.

示例,代码段的略微简化版本:

var MyComponent = React.createClass({handleCompanyRemove:函数(e){//...},渲染:函数(){//this === MyComponent 在这个范围内this.props.someArray.forEach(function(item) {//this !== MyComponent,因此 this.handleCompanyRemove 不能//叫做!})}})

正如您从上面的评论中看到的,在 .forEach 的回调中,您不能直接使用 this 而不在外部定义变量或正确绑定函数.

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

绑定回调函数到正确的这个范围.示例:

this.props.someArray.forEach(function(item) {//this === MyComponent 现在也在这个范围内!//所以你可以毫无问题地调用 this.handleCompanyRemove}.bind(this))

如果您使用 Babel/ES6,您可以使用 Fat Arrow 函数语法,以保证 this 作用域继续从父作用域进行回调.示例:

this.props.someArray.forEach((item) => {//this === MyComponent 现在也在这个范围内!//所以你可以毫无问题地调用 this.handleCompanyRemove})

I am fairly new to the Facebook's React world. Their documentation seems to be very good but there are a few areas where I need a little bit of clarity. This is one of them.

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

var CompanyApp = React.createClass({ getInitialState: function() { return {companylist:this.propspanies}; }, handleNewRowSubmit: function( newcompany ) { this.setState( {companylist: this.statepanylist.concat([newcompany])} ); }, handleCompanyRemove: function( company ) { var index = -1; var clength = this.statepanylist.length; for( var i = 0; i < clength; i++ ) { if( this.statepanylist[i]ame === companyame ) { index = i; break; } } this.statepanylist.splice( index, 1 ); this.setState( {companylist: this.statepanylist} ); }, 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.statepanylist} 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.propspany ); return false; }, render: function() { return ( <tr> <td>{this.propspanyame}</td> <td>{this.propspany.ecount}</td> <td>{this.propspany.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.refsame.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.refsame.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" ) );

This is a very good basic explanation of how ReactJS works. Thanks to the author.

But this comment,

var that = this; // TODO: Needs to find out why that = this made it work; Was getting error that onCompanyDelete is not undefined

Why is that necessary? Is this the right way to do it? If not, what is?

Thanks in advance.

解决方案

There's no mystery of "this" that is specific to ReactJS.

This is just a case of standard scoping issues that crop up with callbacks in JavaScript.

When you're in a react component, all methods on the base component will be scoped with the this being the current component, just like any other JavaScript "class".

In your snippet you have a render method which is a function on the base component and therefore this is equal to the component itself. However within that render method you're calling a callback with this.props.clist.forEach, any function callbacks inside the render method will need to be either bound to the correct this scope, or you can do var that = this (although this is an anti-pattern and should be discouraged)`.

Example, slightly simplified version of your snippet:

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

As you can see from the comments above, inside your callback for the .forEach you cannot use this directly without either defining a variable outside, or properly binding the function.

Other options to solve this are:

Binding the callback function to the correct this scope. Example:

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

If you're using Babel/ES6 you can use the Fat Arrow function syntax which guarantees that this scope continues to the callback from the parent scope. Example:

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

更多推荐

“这个"之谜在 ReactJS 中

本文发布于:2023-11-08 18:49:20,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1570141.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:之谜   quot   ReactJS

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!