6

Not sure the title is totally clear (wasn't sure how to phrase it) so let me explain.

I'd like to try and store a list of component names in an array, then loop through using map (or suitable equivalent) in order to display each array value as a JSX component.

So something along the lines of this (appreciate this code doesn't work, just trying to show what I'm hoping to achieve):

render(){
  let links = ['DashboardLink', 'CoursesLink', 'AssignmentsLink'];
  return (
    <div>{
      links.map((Link) => {
        return <Link key={Link} />
      }
    }</div>
  )
}

Ideally the result would be:

<div>
  <DashboardLink key='DashboardLink' />
  <CoursesLink key='CoursesLink' />
  <AssignmentLink key='AssignmentLink' />
</div>

and each component would then render within the div.

I'm very new to React and ES6 so apologies for any glaring mistakes.

Thanks!

2

3 Answers 3

6

You can use a helper function then:

 render(){
   var links = ['DashboardLink', 'CoursesLink', 'AssignmentsLink'];
   var findComponent: function (name){
     switch (name){
         case 'DashboardLink':
             return (<DashboardLink />);
         case 'CoursesLink':
             return (<CoursesLink />);
         case 'AssignmentsLink':
             return (<AssignmentsLink />);
         default:
             return null; //You might want to return something else here//
     }
   }; 
   return (
     <div>
       links.map((Link) => {
         return findComponent(Link);
       }
     </div>
  );
}

You can place this function at other places too...

Use React.createElement method to create custom components: First argument is name of tag, second is a object with properties, and you can add children as third argument.

render(){
   var links = ['DashboardLink', 'CoursesLink', 'AssignmentsLink'];
   return (
     <div>
       links.map((Link) => {
         return React.createElement(Link, {key: Link});
       }
     </div>
  );
}

Refer: https://facebook.github.io/react/docs/glossary.html

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

5 Comments

Problem is that this is rendering <DashboardLink></DashboardLink> etc. to the DOM. I'm wanting the <DashboardLink /> component to render itself - if that makes sense?
@Chris What do you mean render itself?
So the strings in the array are the names of React components which have been imported from other modules. Each of them contains a div with an SVG element. When I try this solution, I get <DashboardLink></DashboardLink> rendered literally to the DOM as an empty xml element. What I actually want is for the <div><svg /></div> contained within each component to be rendered.
Then you've to add a helper function that renders that component by checking the string value.
Makes sense, but how would that function look? Sorry - like I said, very new to this
1

Why not do something like this?

import CoursesLink from 'components/CoursesLink';
import DashboardLink from 'components/DashboardLink';
import AssignmentsLink from 'components/AssignmentLink';

getComponentByName(name) {
  switch(name):
    case 'DashboardLink':
      return DashboardLink
    case 'AssignmentsLink':
      return AssignmentsLink;
    case 'CoursesLink':
      return CoursesLink;
    default:
      return <div />
}
render() {
  const links = ['DashboardLink', 'AssignmentLink', 'CoursesLink'];
  return (
    <div>
      {links.map(link => React.createElement(getComponentByName(link), key={link}))}
    </div>
  )
}

Comments

1

Alternatively, make links an array of functions and use something else key (or the name of the function):

render(){
  let links = [DashboardLink, CoursesLink, AssignmentsLink];
  return (
    <div>{
      links.map((Link, index) => {
        return <Link key={index} />
        // or
        // return React.createElement(Link, {key: index});
      }
    }</div>
  )
}

Your original code doesn't work because React expects Link to resolve to a function, not a string.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.