1

I have this sidebar component and I want to show the sidebar elements differently if the user is a simple user or is admin.

I have this isManager boolean saved in my state. If isManage is true, I want to loop on the complete links array. If isManager is false, I want to loop on the same array but without the last three elements (a simple array.splice).

But I get confused with JSX syntax and I don't know where to put the condition.

return (
    <div className="flex-item--fill flex--column scops-sidebar-content-container">
      <ul>
        {links.map((link) => (
          <li
            key={link.id}
            className="pad-half--left"
            style={{
              backgroundColor: `${
                activeTabId === link.id ? '#4065d0' : 'var(--color-primary)'
              }`,
            }}
          >
            <button
              className="btn--plain full-width align--left unpad"
              style={{ color: 'white' }}
              onClick={(e) => tabHandler(e, link.id)}
            >
              {link.name}
            </button>
          </li>
        ))}
      </ul>
    </div>
  );

This is my component. Thanks a lot

1
  • Before you return your JSX element inside of the actual function, you could use your isManager flag to create a new array of links to render, where you perform your splice on the existing links array, so you can remove the last 3 links that you don't want if the isManager flag is false. Commented Oct 28, 2021 at 8:06

2 Answers 2

3

In addition to Michael P. Bazos answer:

I usually move as much logic as I can outside JSX, because it makes JSX harder to read and you might accidentially change logic by just editing view things.

Thus I would make the decision just before the JSX.

 const linksToRender = isManager ? links : links.slice(0, -3));

 return (
   <div className="flex-item--fill flex--column scops-sidebar-content-container">
     <ul>
       {linksToRender.map((link) => (
         // ....
       ))}
     </ul>
   </div>
);
Sign up to request clarification or add additional context in comments.

1 Comment

Totally agree. Makes it much easier to read when the JSX is as branch-less as possible.
2
{(isManager ? links : links.slice(0, -3)).map(link => 
   (...JSX FOR LINK...)
)}

links.slice(0, -3) returns the array minus the last three elements. E.g.:

[1, 2, 3, 4, 5].slice(0, -3) => [1, 2]

Note the we are using slice, and not splice which would mutate the links array as it deletes elements from it.

Note2: I wanted to show the minimal path to reach the answer. Naturally, for better clarity, you can add a line of code and store the result of the condition to a local variable, as suggested by René Link (whose name fits perfectly the answer)

6 Comments

You put that condition inside the return?
Exactly where you have your map function, under the <ul> tag
@MichaelP.Bazos links must bу mapped too, so we need something like this: renderLinks = isManager ? links : links.slice(0, -3)); renderLinks.map(link => (...JSX FOR LINK...))
i want to map the links if isManager, and sliced links if !isManager so i guess it's better to put it outside the jsx return
So this is what is done, as the map function applies to whichever array comes out of the conditional expression evaluation.
|

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.