0

Okay, So I've this question which is not as simple as It sounds. I'm designing a web project where I could add my articles. Now the thing is that an article would be a big page which would require a lot of formatting and the other things. Therefore I thought of adding one component per one article that I write.

e.g., Suppose its ArticleX.js

export const ArticleX = () => {
return (
    <div>
        //My article X goes here
    </div>
)}

Similarly suppose like this one I've a lot of other articles too. Let's say, 2 more. ArticleA, ArticleB.

So far so good. Now I've a page called ShowArticles.js which is nothing but another React Component which needs to render all these articles we just talked about.

A simple approach to do that would be doing something like this in ShowArticles:

import {Article X} from './Articles/ArticleX';
import {Article A} from './Articles/ArticleA';
import {Article B} from './Articles/ArticleB';

export const ShowArticles = () => {
    return (
        <div>
            <Article X />
            <Article A />
            <Article B />
        </div>
    )
}

Now the thing is that the articles would go on increasing and each time I'll have to modify the ShowArticles.js file to accommodate the new changes. Instead I want to make an array of these components, If not possible then the component names and then use it to render them dynamically. Think of an array just like some json data being pulled out of a json file.

So Suppose to do that I make an array of Component names.

let travelArticles = [
    {id: 1, articleName: 'ArticleX', source:'./Articles/ArticleX'},
    {id: 2, articleName: 'ArticleA', source:'./Articles/ArticleA'},
    {id: 3, articleName: 'ArticleB', source:'./Articles/ArticleB'}
];

Now the question is, how can I use this array to reframe my ShowArticles.js file so that each of these component name and source is taken and then that information is used to : 1. Import that component from the source 2. Render that component inside ShowArticles.js

export const ShowArticles = ({travelArticles}) => {
    return (
        <div>
            // How to import components using source and name in travelArticles and then use that information to render them ?
        </div>
    )
}

Now If I'm able to do something like this, all I'll need to do is to create the new article and then add it's name and source in the array. Rest everything would be taken care by the code itself and also I would be able to use this array to show some featured content on some other page than just ShowArticles.js

Thanks in advance!

4
  • 3
    Is there a reason you don't just have an Article component and then pass article-specific details as props to it? Commented Jan 28, 2020 at 1:18
  • Take a look at universal components. Commented Jan 28, 2020 at 1:44
  • I would suggest using a template "Article" component that contains styling and layout, and importing your content as markdown or html and setting the inner html of the Article component for each page. Commented Jan 28, 2020 at 2:15
  • Well, yes because an article could contain any information (including differently styled font, paragraphs, containers to images embedded almost anywhere. If I make a component and pass all these values as props I'll simply loose that functionality. I mean I won't loose it but then what about when I want to show an image between two paragraphs? I cannot do something like that using props unless and until I already know when and where that particular item has to be put inside that component and this thing would also vary from one article to another. Commented Jan 28, 2020 at 2:33

1 Answer 1

1

You can use dynamic imports

let travelArticles = [
    {id: 1, articleName: 'ArticleX', source:'./Articles/ArticleX'},
    {id: 2, articleName: 'ArticleA', source:'./Articles/ArticleA'},
    {id: 3, articleName: 'ArticleB', source:'./Articles/ArticleB'}
];

export const ShowArticles = ({travelArticles}) => {
    const [components, setComponents] = useState([]); 
    useEffect(() => {
      const promises = travelArticles.map(art => import(art.source).then(mod => mod.default));
      Promise.all(promises).then(comps => setComponents(comps));
    }, []);
    return (
        <div>
            {components.map((Article, index) => <Article {...travelArticles[index]} />)}
        </div>
    )
}

Sign up to request clarification or add additional context in comments.

4 Comments

you might need to tweak little bit since it's not something I've tested in real scenario
It says that It cannot find module './Articles/ArticleX'.
@DivyamDhadwal Just google how dynamic imports work, maybe your path is invalid
Well, I checked how dynamic imports work. I tried reframing my code but I get one error or the other. I mean even If I do that same things as described in some other stackoverflow threads, I still run into an issue. I even used a third party file called react-loadable. Even that too is not working for me either. I don't understand what is going on but this issue is really pissing me off. I've stuck for more than 2 days now and I don't know what to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.