React или Next.js внутренне очищают свойства класса?

В приведенном ниже коде я вижу, что 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>
            );
        }
    }

person John Vandivier    schedule 12.08.2018    source источник
comment
Если вы console.log(this.mBaseService) либо в конструкторе, либо в fHandleOnDrop, я думаю, вы увидите, что он доступен в обоих местах. Я не уверен, почему вы не можете видеть это в отладчике.   -  person Tholle    schedule 12.08.2018
comment
Это правда. Странный. Если я вызову console.log(this.mBaseService) в fHandleOnDrop, я увижу ожидаемый результат, даже если я нахожусь в инструментах разработчика и вывожу this.mBaseService в консоль, он приходит как неопределенный. Я все еще хотел бы знать, почему, но я закрою, если это рекомендуется.   -  person John Vandivier    schedule 12.08.2018
comment
@Tholle, это отвечает на второй вопрос, который у меня тоже был. Вы видите, как это class extends Page? Ну, у Page тоже есть mBaseService = new ServiceBaseService();, но он не показывался у меня при отладке. Теперь, если я прокомментирую это свойство в дочернем классе и console.log увижу его, хотя если я debugger запрошу на консоли, оно не будет определено.   -  person John Vandivier    schedule 12.08.2018


Ответы (1)


Эта проблема, вероятно, связана с тем, как код транспилируется с помощью Babel. Как объясняется в этом связанном ответе, поля класса (методы со стрелками) переносятся в код конструктора, а 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 был настроен так, чтобы не передавать стрелки в цель ES5, не используя предустановку es2015.

Независимо от этих опасений, всегда есть вероятность, что такое поведение характерно для определенных инструментов разработки.

person Estus Flask    schedule 12.08.2018
comment
Спасибо! Вы не только ответили на вопрос, но и предоставили обходной путь... в котором я даже не был уверен, что это возможно - person John Vandivier; 12.08.2018
comment
Рад, что это помогло. - person Estus Flask; 12.08.2018