Home > Back-end >  conditionally change an HTML tag at the same level depending on a condition
conditionally change an HTML tag at the same level depending on a condition

Time:10-08

I have this block of code

const route="";
return (
    <Link to={route}>
     </p>{route?'click':'No click'}
    </Link>
  )

I want that if the route variable contains something, I want <Link> to enclose the <p>, but otherwise I want a <> to close it. example:

const route="/home";
return (
    <Link to="/home">
      <p>click</p>
    </Link>
  )

const route="";
return (
    <>
     <p>No click</p>
    </>
  )

How can I do this?

I was thinking of something like this, but I know it doesn't make sense.

{route && <Link>
  <p> 
</Link>}

Note: the p tag is an example, there I can have many components so the idea is not to duplicate code.

    <Link to="/home">
      <ComponentA/>
      <ComponentB/>
      <ComponentC styles{mystyles}/>
      {var && <ComponentD/>}
      <ComponentE/>
      <ComponentF/>
    </Link>

CodePudding user response:

You're on the right track. The simplest way would be something like

{route === something ? (
  <Link><p>Click</p></Link>
) : (
  <p>No Click</p>
)}

If you have a lot of content and really want to go the DRY route, you could always create a helper function that returns the content like so:

const getContent = hasRoute => <p>{hasRoute ? 'Click' : 'No click'}</p>
const hasRoute = !!route
{hasRoute ? <Link>{getContent(hasRoute)}</Link> : getContent(hasRoute)}

Finally, for maximum reusability, I guess you could just create a <NoLink> wrapper element around a normal paragraph, and dynamically set a <Container> alias to either <Link> or <NoLink> and it should work fine:

const isLink = !!route
const NoLink = ({children}) => <p>{children}</p>
const Content = isLink ? Link : NoLink
return (
  <Content>
    {isLink ? 'Click' : 'No Link'}
  </Content>
)

Personally, if it's just a small amount of content, I would go with the first approach to reduce code complexity since the 2nd and 3rd add needlessly larger amounts of mental loopholes to understand what you're doing. And only make sense with larger amounts of content.

Also, keep in mind that the fragment you added (<></>) does nothing when you are only returning a single childlike in your example. It's only necessary when you are returning more than one child.

CodePudding user response:

{route && route != '' ? <Link>
  <p> 
</Link> : null}

CodePudding user response:

{route ? (
    <Link to={route}><p>...</p></Link>
  ) : (
    <p>...</p>
  )
}

If the contents of the p tag are the same on either occasion you could also assign those content to a variable to make the code the slightest bit more DRY:

const content = <p>...</p>;

return ({route ? (
    <Link to={route}>{content}</Link>
  ) : (
    content
  )
});
  • Related