简体   繁体   中英

How to wrap a container inside a map function with conditional in JSX - TypeScript

So I have an array of objects that are iterated by a .map() function, inside it I want to have a condition, if the object index is > 1 I want to wrap it in a div with a class.

Here's what I've got so far, but it doesn't wrap all videos in one single .main-videos div :

Thanks

object.map((object, index) => {
return (
    <>

        {index === 0 && (
            <div className="main-image" >
            {<img>}
            </div>
        )}

        {index > 1 && (
            <div className="main-videos">
            {<video>}
            </div>
        )}
</>
);
})}


What I basically want to do is this:


object.map((object, index) => {
return (
    <>

        {index === 0 && (
            <div className="main-image" >
            {<img>}
            </div>
        )}

        {index === 1 && (<div className="main-videos">)}
            {index > 1 && (<video>)}
        {index === object.length && (</div>)}
        
</>
);
})}

I would try a bit differently as the following:

<div className={index === 0 ? 'main-image' : 'main-videos'}>
   { index === 0 ? <img /> : <video /> }
</div>

Of course the necessary attributes are missing but you can see the logic. I like to use conditional rendering with Ternary Operator . Read from the documentation:

The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark (?), then an expression to execute if the condition is truthy followed by a colon (:), and finally the expression to execute if the condition is falsy. This operator is frequently used as a shortcut for the if statement.

In this way you don't need also the React.Fragement <></> because you have a single element.

You can render the <img /> outside of the loop, and slice the loop to render the <video /> inside the video container:

const Example = () => {
  if(!object.length) return null; // don't render anything when there aren't any items

  return (
    <>
      <div className="main-image" >
        <img />
      </div>
      
      <div className="main-videos">
        {object.slice(1).map(() => (
          <video />
        ))}
      </div>
    </>
  )
};

If the object array comes from props or state, you can use destructuring with array rest to get an array of videos:

const Example = ({ object: [img, ...videos] }) => {
  if(!img) return null; // don't render anything when there aren't any items

  return (
    <>
      <div className="main-image" >
        <img />
      </div>
      
      <div className="main-videos">
        {videos.map(() => (
          <video />
        ))}
      </div>
    </>
  )
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM