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

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.