3

I want to loop over a bunch of custom elements and give them parent to child relationship. So arr[0] will be child of arr[1], which will be the child of arr[2] ...

The following method adds <WrapperDraggable/> elements to the boxes array.

addElement=(count,zIdx) => {
    var newDom = <WrapperDraggable count={count} id={"portal"+count.toString()}
                  zIdx={zIdx} width={count*175} height={count*175}/>
    this.setState({boxes:this.state.boxes.concat(newDom)})
}

I thought of using portals to port boxes[0] to boxes[1]'s id and so on. So for boxes length 2, I want to make a DOM structure like,

<div id="portal3"/>
    <WrapperDraggable id="portal2"/>
        <WrapperDraggable id="portal1"/>

However, when I am trying to use react portals to render a div and attach it to another div with id "portal",

<div id={"portal"+(this.state.boxes.length)}>
{this.state.boxes.map((box,index)=>{
    {ReactDOM.createPortal(box, document.getElementById("portal"+(this.state.boxes.length-index).toString()))}
})}

For simplicity imagine the boxes array is already in reverse order.

I don't get any attached to the outermost portal div. The console also doesn't give me any error messages.

Am I doing something wrong? If so, how can I implement a similar behavior in my code?

Thanks in advance.

  • Are you getting any errors/warnings etc in browser console? Also, please post your relevant component code here. It is difficult to analyse from only 2 lines. – Sunil Chaudhary May 10 '20 at 10:23
  • @SunilChaudhary Thanks for your feedback. I have edited the question to include more information. Let me know if something in unclear. And, I don't get any error/warnings in the console. – Shubham Kumar May 10 '20 at 16:19

1 Answers1

1

The issue seems to be in the map function. You are not returning anything from the function.

Return properly and it should work fine.

{this.state.boxes.map((box,index)=>{
    return ReactDOM.createPortal(  //Return here
        box,
        document.getElementById("portal"+(this.state.boxes.length-index).toString())
    )
)}

Hope it helps. Revert for any doubts/clarifications.

Sunil Chaudhary
  • 4,481
  • 3
  • 22
  • 41
  • Thanks a lot, its working now. You saved me from a lot of headache. – Shubham Kumar May 10 '20 at 18:28
  • Hi one more clarification, I get an error "Target container is not a DOM element." when in the map I am trying to port boxes[1] to boxes[0]'s id. How can I achieve the parent-child relationship that I want? Thanks in advance. – Shubham Kumar May 10 '20 at 20:47
  • This issue generally comes when the child is ported to the parent which is not present in the DOM. Try console.log your parent element to see if it exists at the time React.createPortal is run. You might get some help from [/react-and-using-reactdom-createportal-target-container-is-not-a-dom-element](https://stackoverflow.com/questions/54660685/react-and-using-reactdom-createportal-target-container-is-not-a-dom-element) and [here](https://github.com/storybookjs/storybook/issues/4604) – Sunil Chaudhary May 11 '20 at 07:33
  • 1
    As suspected, the element was null at the time react portal was being run. So I decided to use React.forwardRef to pass the ref of the elements to a different array and and pass that in React.createPortal. Since ref is attached lazily so I get the required result without any errors. Thanks for the help! – Shubham Kumar May 12 '20 at 07:21