leefsmp / Re-Flex

Resizable Flex layout container components for advanced React web applications
https://leefsmp.github.io/Re-Flex/index.html
MIT License
639 stars 72 forks source link

Access canvas within re-flex element #119

Closed shanebishop1 closed 3 years ago

shanebishop1 commented 3 years ago

Hi,

I have a canvas element that is wrapped by the re-flex container and an element. There is a function that displays graphics on the canvas once the component is first rendered. I had been using a useEffect function to accomplish this by accessing the canvas with a React useRef. Also, I gave the canvas element an ID attribute and was able to access it using document.getElementByID.

Now, when the canvas is wrapped by re-flex, once the component is rendered and the useEffect is run, it cannot find any element with my given ID nor does the ref have anything assigned to it, so I cannot access a reference to the canvas. I read here that re-flex creates a clone of wrapped elements. Does this mean it deletes/invalidates any DOM/react references? If so, how can I access this canvas if it is wrapped? Any fix or workaround would be appreciated.

Thanks!

leefsmp commented 3 years ago

So if you use a ref there should be no need for you to use an Id to find your element. I am using complex layouts with refs and I don't have issues to work with refs in my apps, maybe your problem is somewhere else or it's a specific configuration that is causing it.

It would be useful if you can provide a codpen/sandbox demo that reproduce the problem. Here is an example if you need.

shanebishop1 commented 3 years ago

@leefsmp Here is a quick codepen reproducing the issue. It's a simple BabylonJS scene loaded into a canvas. If you remove the re-flex components, it loads fine (you should see a 3D box and a purple background in the canvas). Also, note how the canvas element is printed in the console.

With the re-flex components added, the reference is printed as null and the scene does not load. If you could take a look and let me know if you need any more info, that would be great.

Without re-flex: Screen Shot 2021-03-28 at 8 21 19 PM

With re-flex: Screen Shot 2021-03-28 at 8 21 03 PM

leefsmp commented 3 years ago

That isn't a reflex issue, it's a hook/ref issue, I was taking a quick look at this article which explains why your ref is not initialized inside your useEffect hook.

Here is a modified version of the code.

I'm personally not a big fan of hooks, to me they help solve functional components only for very simple situations, look in that example how things get more complicated, the same code with a class and a componentDidMount handler would be much simpler and clearer IMO.

Anyway, I also added a bit of css that was lacking in your example, for example you would most likely wish the canvas to take a the whole upper space, in that case you also need to trigger a resize when that element is being resized, for that I would suggest you wrap the whole babylon canvas in its own component and check the width/height of the canvas then invoke engine.resize() when those have been modified. You can use ReflexElement.propagateDimensions = {true} for that purpose.

Hope that helps.

leefsmp commented 3 years ago

Here is a basic demo than illustrates what I said above, the renderer will be only resized if needed.