React 或 Next.js 内部清理 Class 属性?
Do React or Next.js Internally Clean Class Properties?
在下面提供的代码中,我可以看到 this.mBaseService
定义在第一个 debugger
之上,但不在第二个 debugger
.
之下
谁能解释一下为什么会这样?我的一种理论是 React 或 Next.js 可能在内部清除属性。
import Link from 'next/link';
import React, { Component, Fragment } from 'react';
import ReactDropzone from 'react-dropzone';
import { Container, Row, Col, Button, Jumbotron, ListGroup, ListGroupItem } from 'reactstrap';
import DefaultHomeView from '../components/default-home-view';
import Page from '../components/page';
import EteeReport from '../components/etee-report';
import Layout from '../components/layout';
import { ServiceBaseService } from '../services/service-base/service-base.service';
export default class extends Page {
mBaseService = new ServiceBaseService();
constructor(props) {
super(props);
this.state = {
files: [],
};
console.log('it exists!', this.mBaseService);
debugger;
//this.mBaseService = new ServiceBaseService();
}
fHandleOnDrop = async files => {
debugger;
const oResponse = await this.mBaseService.fpPost('/reports', {
oDataToPost: JSON.stringify(files),
});
// TODO: if valid csv then parse and chart the data
this.setState({
files: this.state.files.concat(files),
});
};
fClearFiles = () => {
this.setState({
files: [],
});
};
render() {
return (
<Layout {...this.props} navmenu={false} container={false}>
{!this.state.files.length && (
<DefaultHomeView {...this.props} fHandleOnDrop={this.fHandleOnDrop} files={this.state.files} />
)}
{this.state.files.length && <EteeReport {...this.props} {...this.state} fClearFiles={this.fClearFiles} />}
</Layout>
);
}
}
此问题可能与使用 Babel 转译代码的方式有关。如 this related answer 中所述,class 字段(箭头方法)被转换为构造函数代码,并且 this
被替换为 _this
、_this2
等临时变量,其中需要模仿箭头中词法 this
的行为。
属性 在调试器中的 this
上可能不可用,但在临时 _this?
变量上可用,该变量在原始代码中被认为是正确的上下文。
在这种特定情况下,这是由于 fHandleOnDrop
作为回调传递的事实引起的:
<DefaultHomeView {...this.props} fHandleOnDrop={this.fHandleOnDrop} files={this.state.files} />
这意味着 this.props.fHandleOnDrop()
已被取消引用并被错误调用 this
,而该函数在内部使用 _this?
变量来引用正确的上下文:
fHandleOnDrop = async files => {
console.log(this.mBaseService) // should be ok
eval('console.log(this.mBaseService)') // should fail
如果 Babel 配置为不使用 es2015
预设不将箭头转换为 ES5 目标,则情况可能不会如此。
不管这些问题,这种行为总是有可能是特定开发工具所特有的。
在下面提供的代码中,我可以看到 this.mBaseService
定义在第一个 debugger
之上,但不在第二个 debugger
.
谁能解释一下为什么会这样?我的一种理论是 React 或 Next.js 可能在内部清除属性。
import Link from 'next/link';
import React, { Component, Fragment } from 'react';
import ReactDropzone from 'react-dropzone';
import { Container, Row, Col, Button, Jumbotron, ListGroup, ListGroupItem } from 'reactstrap';
import DefaultHomeView from '../components/default-home-view';
import Page from '../components/page';
import EteeReport from '../components/etee-report';
import Layout from '../components/layout';
import { ServiceBaseService } from '../services/service-base/service-base.service';
export default class extends Page {
mBaseService = new ServiceBaseService();
constructor(props) {
super(props);
this.state = {
files: [],
};
console.log('it exists!', this.mBaseService);
debugger;
//this.mBaseService = new ServiceBaseService();
}
fHandleOnDrop = async files => {
debugger;
const oResponse = await this.mBaseService.fpPost('/reports', {
oDataToPost: JSON.stringify(files),
});
// TODO: if valid csv then parse and chart the data
this.setState({
files: this.state.files.concat(files),
});
};
fClearFiles = () => {
this.setState({
files: [],
});
};
render() {
return (
<Layout {...this.props} navmenu={false} container={false}>
{!this.state.files.length && (
<DefaultHomeView {...this.props} fHandleOnDrop={this.fHandleOnDrop} files={this.state.files} />
)}
{this.state.files.length && <EteeReport {...this.props} {...this.state} fClearFiles={this.fClearFiles} />}
</Layout>
);
}
}
此问题可能与使用 Babel 转译代码的方式有关。如 this related answer 中所述,class 字段(箭头方法)被转换为构造函数代码,并且 this
被替换为 _this
、_this2
等临时变量,其中需要模仿箭头中词法 this
的行为。
属性 在调试器中的 this
上可能不可用,但在临时 _this?
变量上可用,该变量在原始代码中被认为是正确的上下文。
在这种特定情况下,这是由于 fHandleOnDrop
作为回调传递的事实引起的:
<DefaultHomeView {...this.props} fHandleOnDrop={this.fHandleOnDrop} files={this.state.files} />
这意味着 this.props.fHandleOnDrop()
已被取消引用并被错误调用 this
,而该函数在内部使用 _this?
变量来引用正确的上下文:
fHandleOnDrop = async files => {
console.log(this.mBaseService) // should be ok
eval('console.log(this.mBaseService)') // should fail
如果 Babel 配置为不使用 es2015
预设不将箭头转换为 ES5 目标,则情况可能不会如此。
不管这些问题,这种行为总是有可能是特定开发工具所特有的。