INuke
INuke

Reputation: 303

how to render component from .map() in react

So im trying to not duplicate code and probably over complicating this but im very curious if there is a way for a system like this to work

        <Drawer anchor="right" open={sideBarOpen} onClose={toggleSideBar}>
          <List className={classes.sideBar}>
            {[
              ["test1", <LockOpenIcon />],
              ["test2", <LockOpenIcon />],
              ["test2", <LockOpenIcon />],
            ].map(({ text, icon }, index) => (
              <Fragment key={index}>
                <ListItem button>
                  <ListItemIcon>{icon}</ListItemIcon>
                  <ListItemText primary={text} />
                </ListItem>
                <Divider />
              </Fragment>
            ))}
          </List>
        </Drawer

where I map over an array of pairs of [text, iconComponent] and then render the iconComponent in the following element. this is producing no errors (but also not rendering anything in the ) and if theres not a way then thats cool but any help would be appreciated.

Upvotes: 0

Views: 534

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074088

Yes, it's possible, and you've mostly done it right. You just used object destructuring ({text, icon}) where you should have used iterable destructuring ([text, icon]):

<Drawer anchor="right" open={sideBarOpen} onClose={toggleSideBar}>
    <List className={classes.sideBar}>
        {[
            ["test1", <LockOpenIcon />],
            ["test2", <LockOpenIcon />],
            ["test2", <LockOpenIcon />],
        ].map(([ text, icon ], index) => (
            <Fragment key={index}>
                <ListItem button>
                    <ListItemIcon>{icon}</ListItemIcon>
                    <ListItemText primary={text} />
                </ListItem>
                <Divider />
            </Fragment>
        ))}
    </List>
</Drawer>

However, if the values are hardcoded like that, you might consider abstracting the repeated part of that into its own component:

const MyListItem = React.memo(({text, icon}) => (
    <ListItem button>
        <ListItemIcon>{icon}</ListItemIcon>
        <ListItemText primary={text} />
    </ListItem>
));

(The React.memo is just because I figure this doesn't change unless text or icon changes.)

Then it's:

<Drawer anchor="right" open={sideBarOpen} onClose={toggleSideBar}>
    <List className={classes.sideBar}>
        <MyListItem text="test1" icon={<LockopenIcon/>} />
        <Divider />
        <MyListItem text="test2" icon={<LockopenIcon/>} />
        <Divider />
        <MyListItem text="test3" icon={<LockopenIcon/>} />
    </List>
</Drawer>

Upvotes: 1

Related Questions