I'd like to import an array called "content" from one of several different files. I'd like to set which module to pull from based on a const I create (pageName), which titles the page in the PageTitle component. I'll concatenate this to "modulePath" which is located in a directory outside my components folder. But I'm having trouble with importing content when I reference the module path as a constant.
import React from "react"
import PageTitle from "./PageTitle"
import BuildItems from "./BuildItems"
function camelize(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) {
if (+match === 0) return ""; // or if (/\s+/.test(match)) for white spaces
return index === 0 ? match.toLowerCase() : match.toUpperCase();
});
}
const pageName = "Settings";
const modulePath = "../" + camelize(pageName);
import content from modulePath;
function View() {
return (
<div className="View">
<PageTitle content={pageName} layout="mini" />
{content.map(BuildItems)}
</div>
);
}
export default View;
src folder structure is as follows:
src/
components/
App.js
BuildItems.js
PageTitle.js
View.js
index.js
settings.js
It works fine when I replace import content from modulePath with import content from "../settings". But I'm wishing to do this dynamically by changing the const pageName to anything else (essentially switching out content).
Top-level imports must be static strings known at compile time. For your use case, you should use a dynamic import instead (await import(...)):
import React from "react"
import PageTitle from "./PageTitle"
import BuildItems from "./BuildItems"
function camelize(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) {
if (+match === 0) return ""; // or if (/\s+/.test(match)) for white spaces
return index === 0 ? match.toLowerCase() : match.toUpperCase();
});
}
const pageName = "Settings";
const modulePath = "../" + camelize(pageName);
function View() {
const [content, setContent] = useState(null);
useEffect(() => {
(async () => {
// using the `await import(modulePath)` syntax to import a path based on a variable
setContent(await import(modulePath))
})();
}, [])
if (content === null) {
return <div>Loading...</div>
}
function load() {
<PageTitle content={pageName} layout="mini" />
return content.map(BuildItems);
}
return (
<div className="View">
{load()}
</div>
);
}
export default View;