Динамический импорт в реакции не работает при попытке импортировать компонент в другой каталог

На самом деле мы ошибались. Несмотря на то, что Java по умолчанию не позволяет переопределять статические методы, если вы тщательно изучаете документацию классов класса и метода в Java, вы все равно можете найти способ эмуляции статических методов, переопределяющих следующие методы:

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;

class RegularEmployee {

    private BigDecimal salary = BigDecimal.ONE;

    public void setSalary(BigDecimal salary) {
        this.salary = salary;
    }
    public static BigDecimal getBonusMultiplier() {
        return new BigDecimal(".02");
    }
    public BigDecimal calculateBonus() {
        return salary.multiply(this.getBonusMultiplier());
    }
    public BigDecimal calculateOverridenBonus() {
        try {
            // System.out.println(this.getClass().getDeclaredMethod(
            // "getBonusMultiplier").toString());
            try {
                return salary.multiply((BigDecimal) this.getClass()
                    .getDeclaredMethod("getBonusMultiplier").invoke(this));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        return null;
    }
    // ... presumably lots of other code ...
}

final class SpecialEmployee extends RegularEmployee {

    public static BigDecimal getBonusMultiplier() {
        return new BigDecimal(".03");
    }
}

public class StaticTestCoolMain {

    static public void main(String[] args) {
        RegularEmployee Alan = new RegularEmployee();
        System.out.println(Alan.calculateBonus());
        System.out.println(Alan.calculateOverridenBonus());
        SpecialEmployee Bob = new SpecialEmployee();
        System.out.println(Bob.calculateBonus());
        System.out.println(Bob.calculateOverridenBonus());
    }
}

Результат:

0.02
0.02
0.02
0.03

, чего мы пытались достичь:)

Даже если мы объявим третью переменную Carl как RegularEmployee и назначим ей экземпляр SpecialEmployee, мы будем все еще имеют вызов метода RegularEmployee в первом случае и вызов метода SpecialEmployee во втором случае

RegularEmployee Carl = new SpecialEmployee();

System.out.println(Carl.calculateBonus());
System.out.println(Carl.calculateOverridenBonus());

просто посмотрите на консоль вывода:

0.02
0.03

;)

2
задан JayD 18 January 2019 в 13:06
поделиться

2 ответа

Если FooterComp находится под src, путь должен быть './FooterComp/Footer', а не '../FooterComp/Footer'

<час>

Редактировать

Index.js

[110 ]

FirstComponent.js

render() {
      const { module: Component } = this.state;
    return (
      <div className="App">
        <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
        {Component && <Component path= '../FooterComp/Footer' />}
      </div>
    );
  }
0
ответ дан Derf Mongrel 18 January 2019 в 13:06
поделиться

Существует ограничение при использовании динамического импорта с «переменными частями», такими как import(`${path}`), поскольку ${path} является переменной.

Во время создания пакета Webpack

В вашем случае, когда компонент import(`${path}`) в Dynamic назывался webpack, создавал пакет. Этот комплект был для FirstComponent компонента. Внутри этого пакета веб-пакет содержит список компонентов, которые можно динамически импортировать с помощью «переменных частей» в компоненте FirstComponent. Он содержал только файлы, которые находились в той же папке, где находился компонент FirstComponent. Это потому, что вы использовали import(`${path}`) в FirstComponent.

Все это происходит потому, что webpack при компиляции не знает, какой будет точный путь импорта во время выполнения, так как вы используете динамический импорт с «переменными частями».

Во время запроса приложения React

Когда в компоненте Dynamic было выполнено import(`${path}`). Пакет для FirstComponent был запрошен. Как только пакет был получен, и он выполнил свой код, и path, который вы указали в качестве компонента props - FirstComponent, не было в списке компонентов, которые можно динамически импортировать с помощью «переменных частей».

То же самое относится и к компоненту Dynamic, если вы попытаетесь динамически импортировать файлы с «переменными частями» для файлов, которые находятся вне папки src, вы получите ту же ошибку.

Итак, чтобы решить эту проблему, у вас есть пара опций

1) Поместите оба файла в одну папку

, т.е.

'src/Components/FirstComponent'

'src/Components/Footer'

И используйте

// In FirstComponent.js
   componentDidMount() {
      const { path } = this.props;
      import(`${path}`)
      .then(module => this.setState({ module: module.default }))   
   }


{Component && <Component path='./Footer' />} // Index.js

2) быть более точным, насколько это возможно

т.е.

// In FirstComponent.js
 componentDidMount() {
      const { path } = this.props;
      import(`../FooterComp/${path}`)
      .then(module => this.setState({ module: module.default }))   
 }

И использовать

{Component && <Component path='Footer' />} //  In index.js

ОБНОВЛЕНИЕ

Пакет, созданный веб-пакетом для componentDidMount:

1) для динамического импорта с переменными, но более конкретным способом, например import(`../FooterComp/${path}`)

 _createClass(App, [{
        key: "componentDidMount",
        value: function componentDidMount() {
          var _this2 = this;

          var path = this.props.path;
          // "import(`../FooterComp/${path}`)" is converted to code below
          __webpack_require__(/*! ../FooterComp */ "./src/FooterComp lazy recursive ^\\.\\/.*$")("./" + path)
          .then(function (module) {
            return _this2.setState({ module: module.default });
          });

Код для [ 1126] в связке

/***/ "./src/FooterComp lazy recursive ^\\.\\/.*$":
/*!**************************************!*\
  !*** ./src/FooterComp lazy ^\.\/.*$ ***!
  \**************************************/
/*! dynamic exports provided */
/*! all exports used */
/***/ (function(module, exports, __webpack_require__) {

var map = {
    "./Footer": [
        "./src/FooterComp/Footer.jsx",
        0
    ],
    "./Footer.jsx": [
        "./src/FooterComp/Footer.jsx",
        0
    ]
};
function webpackAsyncContext(req) {
    var ids = map[req];
    if(!ids)
        // Code throwing "ERROR"
        return Promise.reject(new Error("Cannot find module '" + req + "'."));
    return __webpack_require__.e(ids[1]).then(function() {
        return __webpack_require__(ids[0]);
    });
};
webpackAsyncContext.keys = function webpackAsyncContextKeys() {
    return Object.keys(map);
};
webpackAsyncContext.id = "./src/FooterComp lazy recursive ^\\.\\/.*$";
module.exports = webpackAsyncContext;

/***/ })

2) для динамического импорта с переменными, т.е. import(`${path}`)

_createClass(App, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      var _this2 = this;

      var path = this.props.path;
         // "import(`${path}`)" is converted to code below
      __webpack_require__(/*! . */ "./src/Components lazy recursive ^.*$")("" + path).then(function (module) {
        return _this2.setState({ module: module.default });
      });

Код для ./src/Components lazy recursive ^.*$

/***/ "./src/Components lazy recursive ^.*$":
/*!**********************************!*\
  !*** ./src/Components lazy ^.*$ ***!
  \**********************************/
/*! dynamic exports provided */
/*! all exports used */
/***/ (function(module, exports, __webpack_require__) {

var map = {
    "./FirstComponent": [
        "./src/Components/FirstComponent.jsx"
    ],
    "./FirstComponent.jsx": [
        "./src/Components/FirstComponent.jsx"
    ]
};
function webpackAsyncContext(req) {
    var ids = map[req];
    if(!ids)
        // Code throwing "ERROR"
        return Promise.reject(new Error("Cannot find module '" + req + "'."));
    return Promise.all(ids.slice(1).map(__webpack_require__.e)).then(function() {
        return __webpack_require__(ids[0]);
    });
};
webpackAsyncContext.keys = function webpackAsyncContextKeys() {
    return Object.keys(map);
};
webpackAsyncContext.id = "./src/Components lazy recursive ^.*$";
module.exports = webpackAsyncContext;

/***/ }),
0
ответ дан JS Engine 18 January 2019 в 13:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: