0

I'm not sure what is the best method to do this but - I have outputted list of divs. When I click on one of them, it gets given a class active. I need to show a component I made (to render) inside this particular class once the div has been clicked on. I am using next.js with react and having been using CSS modules.

Currently I tried: ReactDOM.render( <InnerDisc/>, document.getElementsByClassName(styles.active) ); but I get an error Error: Target container is not a DOM element.

Child (InnerDisc) Component

const InnerDisc = (props) => {
   const active = props.active;

   if (active) {
      return ( 
         <div className={styles.wrapper}>
            <Image className={styles.pic} src="https://picsum.photos/200/300" width={200} height={200}/>
            <Image className={styles.pic} src="https://picsum.photos/200/300" width={200} height={200}/>
            <Image className={styles.pic} src="https://picsum.photos/200/300" width={200} height={200}/>
            <Image className={styles.pic} src="https://picsum.photos/200/300" width={200} height={200}/>
            <Image className={styles.pic} src="https://picsum.photos/200/300" width={200} height={200}/>
            <Image className={styles.pic} src="https://picsum.photos/200/300" width={200} height={200}/>
            <Image className={styles.pic} src="https://picsum.photos/200/300" width={200} height={200}/>
            <Image className={styles.pic} src="https://picsum.photos/200/300" width={200} height={200}/>
         </div>
       );
   }
  
}

export default InnerDisc;

Main App Component

export default function Home() {
   const [discs, setDiscs] = useState([
      { id: 1, top: 100 },
      { id: 2, top: 200 },
      { id: 3, top: 300 },
      { id: 4, top: 400 },
      { id: 5, top: 500 },
      { id: 6, top: 600 },
      { id: 7, top: 700 },
      { id: 8, top: 800 },
      { id: 9, top: 900 },
      { id: 10, top: 1000 },
      { id: 11, top: 1100 },
      { id: 12, top: 1200 }
   ])

   function enlargeDisc(e, num) {
      let t = e.target
      if (t.classList.contains(styles.active)) {
         t.classList.remove(styles.active)
         discRender()
      } else {
         t.classList.add(styles.active)
         discRender()
      }
   }

   function discRender() {
      ReactDOM.render(
         <InnerDisc/>, document.getElementsByClassName(styles.active)
      );
    }

return (
                  <div className={styles.container}>
                  <div className={styles.wrapper}>
                     {discs.map((item) => (
                        <div className ={styles.disc} key={item.id} style=. 
                       {{top: item.top + 'px'}} onClick={(e)=> 
                         enlargeDisc(e, item.id)}> </div>
                         ))}
                       </div>
                  </div>
                </div>
)
}
Laiqa Mohid
  • 461
  • 3
  • 14

1 Answers1

0

First, you're not using "num" at the function, so it can be like this: function enlargeDisc(e) {

      let t = e.target
      if (t.classList.contains(styles.active)) {
         t.classList.remove(styles.active)
         discRender()
      } else {
         t.classList.add(styles.active)
         discRender()
      }
   }

Now that you only have the event has parameter, you could just put the onClick like:

 {discs.map((item) => (
                        <div className ={styles.disc} key={item.id} style=. 
                       {{top: item.top + 'px'}} onClick={enlargeDisc}> </div>

Test what is reciving "enlargeDisc" event with a console.log inside the function, if there is the e.target, you could handle better using const clsList = e.target.classList, so you just need if(classList."property").

Also, you can instead using ReactDOM.render(), make a component Disc and use a State to handle when the class property gonna change or remove.

SDGM21
  • 16
  • 1