динамически импортировать файл по переменной - реагировать на нативный - PullRequest
4 голосов
/ 06 марта 2020

У меня есть путь. json файл, содержащий путь к компоненту

// path.json

{
  "main": "./login/index.js",
  "paths": [
    {
      "name": "login",
      "path": "./login/index.js",
      "image": ""
    }
  ]
}

Я хочу загрузить '. / Login / index. js' файл динамически реагировать на нативный и отображать этот конкретный файл

Моя текущая реализация

const MyComponent = createLazyContainer(() => {
  const componentPath = PathJson.main; // ./login/index.js
  return import(`${componentPath}`); //import error here @ line 7
});

export default MyComponent;

Я получаю следующую ошибку:

Недопустимый вызов в строке 7: import ( "" + componentPath)

Ответы [ 5 ]

3 голосов
/ 12 марта 2020

То, что люди говорили вам в теме, правильно, но я хотел бы добавить одно возможное решение. Все операции импорта / запроса разрешаются во время компиляции, а не во время выполнения, которое вы пытаетесь сделать. К тому времени, когда вы запустите свое приложение, если вы не импортировали файлы, вы не сможете их использовать.

Существует обходной путь, предполагающий, что вы знаете все файлы, которые вы можете заранее, который должен сделать что-то вроде фабрики:

   const possiblePaths = {
     'one': require('path/to/file/1),
    'two': require('path/to/file/2)
}

funtion(type){
    return possiblePaths[type]
}

И затем вы используете его как-то так:

render(){
   const MyComponent = function('one')

  return <MyComponent/>
}

Это более или менее псевдокод, и я не сразу работаю, но, надеюсь, вы поняли идею. Вам нужно сохранить ссылку на каждый импорт, который вам может понадобиться, и затем не использовать импорт, используйте ссылку, созданную для вас во время компиляции.

1 голос
/ 16 марта 2020

Решение 1:

const allPaths = {
  path1: require('file path1'),
  path2: require('file path2')
};
import React from "react";

class Test extends React.Component {
  state = {
    component: null
  };
  componentDidMount() {
    const file1 = allPaths["path1"];
    this.setState({ component: file1 });
  }
}

Soluton 2: для специального использования на выставке expo-asset для динамического импорта файла c

import React from "react";
import { Asset } from "expo-asset";
import * as FileSystem from "expo-file-system";

class Test extends React.Component {
  getDynamicAsset = async (filePath) => {
    let asset = Asset.fromModule(require(filePath));
    await asset.downloadAsync();
    const localUri = asset.localUri;
    return localUri;
  };

  async componentDidMount() {
    const path1 = "file path1";
    const path2 = "file path2";
    const localUri1 = await this.getDynamicAsset(path1);
    const localUri2 = await this.getDynamicAsset(path2);
  }
}

0 голосов
/ 16 марта 2020

На самом деле, проблемы разработки React Native не похожи на разработку для Web .

По этой причине вообще не так важно иметь ленивый загрузка в производство реактивно-нативного проекта. Просто импортируйте все, что хотите, а затем используйте их в любых файлах проекта. все они находятся в комплекте производства, и это совершенно не важно.

Поэтому для этой проблемы я предпочитаю иметь вспомогательный файл для сбора всех выбираемых библиотек и их экспорта:

// helper file
export { default as Index } from './Login';
export { default as OtherComponent } from './OtherComponent';

Тогда, когда вы хотите использовать:

import { Index, OtherComponent } from 'helper';

~~~

render() {
  const MyComponent = someCondition ? Index : OtherComponent;

  return (
    <MyComponent />;
  );
}
0 голосов
/ 16 марта 2020

Я когда-то был в подобной ситуации, когда мне нужно было выполнять импорт по переменной, но это ограничено импортом компонентов внутри компонента , и использует разделение кода ( Изменить: я играю вокруг, чтобы найти решение, не полагаясь на разделение кода, я только что понял, что в вопросе был тег реагировать на родную, и я не думаю, что разделение кода является хорошим выбором для go с в рн). Я не уверен, насколько мой метод мог бы помочь вам, но здесь идет.

Примечания:

  • При импорте папки, содержащей файл index.js(jsx|ts|tsx), этот файл index автоматически разрешается.
  • При импорте из from './login/index.js' обычно выбрасывает «Модуль не найден» Ошибка. Импортируйте from './login/index' или from './login, но я предпочитаю последний, так как он самый короткий и простой.

В path.json:

{
  "main": "./login", // '.js' is removed
  "paths": [
    {
      "name": "login",
      "path": "./login/index.js", // Not sure what this is for, but if necessary, remove the '.js' here as well
      "image": ""
    }
  ]
}

В MyComponent.js:

import React, { lazy, Suspense } from 'react'
import PathJson from './path'

// 1. We need a UI to show while component is being loaded
const Loader = () => <div>{'Loading...'}</div>

// 2. We need a fallback UI if component is not found
const DocUnavailable = () => <div>{'We\'re sorry, but this document is unavailable.'}</div>

// 3. Create a resolver function ('resolver' is just a name I give)
function resolveImport(pathToComponent, FallbackComponent) {
  let componentFound = false
  let RenderComponent = () => <FallbackComponent /> // Assign fallback first
  try {
    if (require.resolve(pathToComponent)) {
      componentFound = true
    }
  } catch (e) { } // Kinda hacky, if you don't mind, but it works
  if (componentFound) {
    // If found, replace fallback with the valid component
    RenderComponent = lazy(() => import(pathToComponent))
  }
  return RenderComponent
}

// 4. Finally, implement it in a component
class MyComponent extends React.Component {

  render() {
    const componentPath = PathJson.main
    const RenderComponent = resolveImport(componentPath, DocUnavailable)
    return (
      <Suspense fallback={<Loader />}>
        <RenderComponent />
      </Suspense>
    )
  }

}

export default MyComponent

Ссылки:

0 голосов
/ 06 марта 2020

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

Допустим, у вас есть три файла index.js, test_1.js и test_2.js, и если вы импортировали только test_1.js в index.js, то React Native будет связывать только эти два файла, оставляя test_2.js.

Таким образом, чтобы ответить на ваш вопрос, даже если динамический импорт c работает в React Native, но поскольку эти файлы не являются частью пакета, вы не сможете их импортировать.

...