【问题标题】:Do React or Next.js Internally Clean Class Properties?React 或 Next.js 是否在内部清理类属性?
【发布时间】:2019-01-19 03:59:01
【问题描述】:

在下面提供的代码中,我可以看到 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>
            );
        }
    }

【问题讨论】:

  • 如果你在构造函数或fHandleOnDropconsole.log(this.mBaseService) 我想你会看到它在两个地方都可以访问。我不确定为什么你在调试器中看不到它。
  • 确实如此。诡异的。如果我在fHandleOnDrop 中调用console.log(this.mBaseService),我会看到预期的结果,即使我在开发工具中并且我将this.mBaseService 登录到控制台,它也是未定义的。我仍然想知道为什么,但如果有人推荐,我会关闭。
  • @Tholle 这回答了我也有的第二个问题。你看这个class extends Page怎么样?好吧,Page 也有 mBaseService = new ServiceBaseService();,但是在调试时它没有显示给我。现在,如果我在子类上评论该属性并且我 console.log 我可以看到它,即使我 debugger 并在控制台上询问它是未定义的。

标签: javascript reactjs ecmascript-6 es6-class next.js


【解决方案1】:

这个问题可能是特定于代码是如何使用 Babel 转译的。正如this related answer 中所解释的,类字段(箭头方法)被转译为构造函数代码,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 目标,则可能不会出现这种情况。

不管这些问题如何,这种行为总是有可能是特定于特定开发工具的。

【讨论】:

  • 谢谢!您不仅回答了问题,而且还提供了一种解决方法……我什至不确定这是否可行
  • 很高兴它有帮助。
猜你喜欢
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
相关资源
最近更新 更多