コンポーネントのパスを含むpath.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)
実際、React Native開発の懸念はWebの開発とは異なります。
この理由だけで、反応ネイティブプロジェクトのプロダクションでlazyロードすることはそれほど重要ではありません。必要なものをインポートして、プロジェクトの任意のファイルで使用するだけです。それらはすべて本番環境のバンドルに含まれており、まったく重要ではありません。
したがって、この問題では、選択可能なすべてのライブラリーを収集してエクスポートするためのヘルパーファイルを用意します。
// 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 />;
);
}
ソリューション:
const allPaths = {
path1: require('file path1').default,
path2: require('file path2').default
};
render(){
const MyComponent = allPaths["path1"];
return <MyComponent/>
}
変数によるインポートを行う必要がある同様の状況にかつてありましたが、これはコンポーネント内のコンポーネントのインポートとそのコード分割を使用します(編集:コード分割に依存せずに解決策を探すために遊んでいます質問では、私はコード分割をRNで行うのに適しているとは思いません)。私の方法がどれだけ役立つかわからないが、ここに行く。
サイドノート:
index.js(jsx|ts|tsx)
ファイルを含むフォルダーをインポートすると、自動的にそのindex
ファイルに解決されます。from './login/index.js'
からインポートすると、通常 'Module not found'エラーがスローされます。 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
参照:
lazy
とSuspense
を使用したコード分割 Reactドキュメントに基づくReactでは、インポートされるすべてのネイティブファイルがバンドルされており、動的にインポートできるのはそれらのファイルのみです。
たとえば、index.js
、test_1.js
、test_2.js
の3つのファイルがあり、test_1.js
にindex.js
のみをインポートした場合、React = Nativeは、test_2.js
を離れた2つのファイルのみをバンドルします。
したがって、動的インポートがReact Nativeで機能する場合でも、質問に答えるために、これらのファイルはバンドルの一部ではないため、インポートできません。