How to append a JSX component inside an item from . map()

Asked

Viewed 48 times

1

I have this line structure:

Resultado da renderização do componente

And my idea is that by clicking on each line, a JSX component is rendered according to the item that was clicked. I got it with the following code, but I feel it’s not the right thing to do.

{itens.map(v => (
    <>
        <div className="tickets-row py-3" onClick={handleDataTicket} idx={v}>
            <div className="text-center">{v}</div>
            <div>Item 1</div>
            <div>Item 2</div>
            <div>{moment().format('DD/MM')}</div>
            <div>Problema</div>
            <div> <BiDownArrow /> </div>
        </div>
        
        {dataTicket[v] &&
            <Teste />
        }
    </>
))}

And the function that is triggered by clicking on div is this:

function handleDataTicket({target}){
    const v = target.parentNode.attributes.idx && target.parentNode.attributes.idx.value
    v && setDataTicket({[v]: !dataTicket[v]})
}

It works and I can pass the parameters just to render the <Teste /> as in: <Teste {...v} />, but that would be the right way to do it?

I would like ideas to improve this code.

1 answer

1


I would say that a more interesting alternative is to extract the part of the code that corresponds to list item for its own component.

So instead of a single component, responsible for the list and its items; you will have two components - one for the list and the other for the list items.

The advantage of this is that each item on the list can encapsulate its state and thus solve the problem in question in a slightly more "declarative" way. See a simple example:

function List({ items }) {
  return items.map((v) => <ListItem key={v.id} data={v} />);
}

function ListItem({ data }) {
  const [isDataTicketVisible, setIsDataTicketVisible] = useState(false);

  function handleDataTicket() {
    setIsDataTicketVisible((prev) => !prev);
  }

  return (
    <div onClick={handleDataTicket}>
      <span>{data.name}</span>
      {isDataTicketVisible && <span>Ticket de {data.id} visível.</span>}
    </div>
  );
}
  • Actually, so it became much easier to control the component, even because it would probably already need to do this control for every time you open make a call to an api to fetch the data related to that item. Thank you so much for your help :D

Browser other questions tagged

You are not signed in. Login or sign up in order to post.